Updating database entry MVC Entity Framework - asp.net-mvc

I have a Payment model with a 'Status' boolean value which defaults to false. Once payment has been made, I need to update that specific payment's 'Status' to true.
Here's the code I've been trying to use to change the specific database entry, but it's just not changing it. What am I doing wrong?
Payment payment = new Payment();
payment = db.Payments.Find(orderId);
db.Entry(payment).State = EntityState.Modified;
payment.Status = true;
db.SaveChanges();
Thanks!
This is what ended up working:
using (var con = new ApplicationDbContext())
{
payment = con.Payments.First(x => x.Id == orderId);
payment.Status = true;
con.Payments.Attach(payment);
var entry = con.Entry(payment);
entry.Property(e => e.Status).IsModified = true;
con.SaveChanges();
}

Payment payment = new Payment();
payment = db.Payments.Find(orderId);
payment.Status = true;
db.Entry(payment).State = EntityState.Modified;
db.SaveChanges();

The reason all of these are failing is because either the Payment object is never attached to the DBContext or the orderId doesn't actually match up with the PK on the Payments table. In order for SaveChanges() to actually work, the object you're changing needs to be tracked by the DBContext, not just have its EntityState set to Modified. Also all these examples seem grossly overcomplicated.
using (var db = new DbContext())
{
// make sure you have the right column/variable used here
var payment = db.Payments.FirstOrDefault(x => x.Id == orderId);
if(payment == null) throw new Exception("Invalid id: " + orderId);
// this variable is tracked by the db context
payment.Status = true;
db.SaveChanges();
}

If you just have your entity id, just do like Ali Golshani said. But if you already have the entity and just want to update, you can do this way:
public void Update(Payment payment, int orderId)
{
//first find the entity to update
Payment oldEntity = DbSet.Find(orderId);
//detach this entity from the DbSet
Db.Entry(oldEntity).State = EntityState.Detached;
//set the state from the entity that you just received to modified
Db.Entry(obj).State = EntityState.Modified;
}
Detaching avoids the error message: "Attaching an entity failed because another entity of the same type already has the same primary key value".
I hope that it helps.

Try this one:
Payment payment;
using (var context = new DBContext()) //replace the name of your context
{
payment = context.Payments.Find(orderId);
}
if(payment != null)
{
payment.Status = true;
}
using (var context = new DBContext()) //replace the name of your context
{
context.Payments.Attach(payment);
context.Entry(payment).State = System.Data.EntityState.Modified;
context.SaveChanges();
}

As mentioned here:
The Find method on DbSet uses the primary key value to attempt to find an entity tracked by the context. If the entity is not found in the context then a query will be sent to the database to find the entity there. Null is returned if the entity is not found in the context or in the database.
So be sure that Payment class looks like this:
public class Payment
{
[Key]
public int Id {get; set;}
public bool Status {get; set;}
}
And your Entry save logic could look like this:
Payment payment = null;
using (var ts = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(1, 0, 0, 0)))
{
using (var context = new DBContext())
{
context.Database.Log = s => { System.Diagnostics.Debug.WriteLine(s); };
payment = context.Payments.Find(orderId);
if(payment != null)
{
payment.Status = true;
context.Entry(payment).State = System.Data.EntityState.Modified;
}
else
{
context.Payments.Add(new Payment(){
Status = true
});
}
context.SaveChanges();
}
ts.Complete();
}
Added transaction scope to be sure that it is properly open and close, and added sql query logging to debug window.

Related

How do i insert data already present in one table into another using Entity framework

Hi I have table called Users which already has id of users who are registered.This table is in different database which is named TrackUsers. Now I am using new database called Terms which has field called ID which should take all ID's from users table and insert into this table.For this i used database first approach.
I am using ASP.NET MVC Entity framework. Below is the code I am using in controller :
public class HomeController : Controller
{
private AppMarketplaceEntities db = new AppMarketplaceEntities();
private InstallTrackerEntities db1 = new InstallTrackerEntities();
public ActionResult Index()
{
List<int> gatewayUserId = new List<int>();
using (var ctx = new InstallTrackerEntities())
{
gatewayUserId = ctx.Gateway_Users.Select(f => f.GatewayuserUID).ToList();
}
using (var ctx2 = new AppMarketplaceEntities())
{
foreach (var id in gatewayUserId)
{
ctx2.AppTerms.Add(new AppTerm() { GatewayuserUID = id });
}
db.SaveChanges();
}
return View();
}
}
}
But still GatewayUserUID is showing null in Appterms table.
Assuming you have 2 .edmx files (and therefore different dbcontexts for each database), are you looking for something like this?
List<int> userids = new List<int>();
using(var ctx = new TrackUsersEntities())
{
userids = ctx.Users.Select(f => f.UserId).ToList();
}
using(var ctx2 = new OtherDatabaseEntities())
{
foreach(var id in userids)
{
ctx2.Terms.Add(new Term() { ID = id });
}
ctx2.SaveChanges();
}
As for where to place the code, I'd put it in the Services layer (if it exists), otherwise in the Controller class.

Save userid on database when create new object

I have a Controller where on the Create action I need the user ID.
Here's the controller.
public ActionResult Create(MyCreateViewModel model)
{
if (ModelState.IsValid)
{
var myobject = new MyObject
{
Attrib1 = DateTime.Now.Date,
Attrib2 = model.Etichetta,
UserId = // I need the user ID...
};
// Save the object on database...
return RedirectToAction("Index");
}
return View(model);
}
I'm using the UserProfile table provided with the SimpleMembership of MVC 4.
Which is the best practice in MVC 4 to manage the userID across the application?
Do I have to include a User attribute inside every Entity class?
Should I use a Session[] variable or what?
You can use this line to get the userId from the UserProfiles table.
var userId = WebSecurity.GetUserId(HttpContext.Current.User.Identity.Name);
You can also use this function to get the users complete profile, including any custom columns you may be populating.
public static UserProfile GetUserProfile()
{
using (var db = new UsersContext())
{
var userId = WebSecurity.GetUserId
(HttpContext.Current.User.Identity.Name);
var user = db.UserProfiles
.FirstOrDefault(u => u.UserId == userId);
if (user == null)
{
//couldn't find the profile for some reason
return null;
}
return user;
}
}

Creating a dropdown list in MVC nhibernate

I'm creating an application in hibernate where i need to create a dropdown list in my Create View.
The dropdownlist items are fetched through a function called getHobbytype() and from that I need to store the selected value into a different database.
I have written this in my controller:
ViewData["Hobby_type"] =
new SelectList(new Hobby_MasterService().GetHobbyType(),"Hobby_Types");
And this in my Create View:
#Html.DropDownListFor(Model =>
Model.Hobby_Types,(IEnumerable<SelectListItem>)ViewData["Hobby_type"])
Through this I'm able to create the dropdown list but it is giving me this error inside my view on the dropdown:
There is no ViewData item of type 'IEnumerable' that has the key 'Hobby_Types'.
Here is my GetHobbyType Method:
public IList<String> GetHobbyType()
{
log.Debug("Started");
ISession session = DataAccessLayerHelper.OpenReaderSession();
IList<String> htype = null;
ITransaction transaction = null;
try
{
transaction = session.BeginTransaction();
htype = session.CreateSQLQuery("SELECT Hobby_Types FROM Hobby_Type").List<String> ();
session.Flush();
transaction.Commit();
}
catch (Exception ex)
{
if (transaction != null && transaction.IsActive)
transaction.Rollback();
log.Error(ex);
}
log.Debug("End");
return htype;
}
Please tell me where I'm going wrong.
Is this a typo:-
#Html.DropDownListFor(Model =>
Model.Hobby_Types,(IEnumerable<SelectListItem>)ViewData["Type"])
Should it not be
#Html.DropDownListFor(Model =>
Model.Hobby_Types,(IEnumerable<SelectListItem>)ViewData["Hobby_type"])
Also your error says 'IEnumerable' that has the key 'Hobby_Types'.
The key in ViewData is case sensitive (not to mention the error has an S on the end)
I would also reccomend using a ViewModel rather than ViewData. See this Google search
edit The GetHobbyType Method returns a List so try this:-
ViewData["Hobby_type"] =
new SelectList(
new Hobby_MasterService().GetHobbyType()
.Select(x => new SelectListItem { Text = x, Value = x }).ToList()
,"Hobby_Types");
I also suggest looking at using a viewmodel as it will save you lots of headaches!
You can try this all.
You have to write a service named GetAllStudents()
public IList<Student> GetAllStudents()
{
log.Debug("Started");
ISession session = DataAccessLayerHelper.OpenReaderSession();
IList<Student> students = null;
ITransaction transaction = null;
try
{
transaction = session.BeginTransaction();
ICriteria criteria = session.CreateCriteria(typeof(Student));
students = criteria.List<Student>();
session.Flush();
transaction.Commit();
}
catch (Exception ex)
{
if (transaction != null && transaction.IsActive)
transaction.Rollback();
log.Error(ex);
}
finally
{
if (transaction != null)
transaction.Dispose();
if (session != null && session.IsConnected)
session.Close();
}
log.Debug("End");
return students;
}
In controller:
ViewBag.std = new StudentService().GetAllStudents(); // ViewBag.std will hold all students.
In create View:
#Html.DropDownListFor(model => model.Name, new SelectList(ViewBag.std, "Id", "Name"), "-- Select --")
First parameter is responsible for Linq expression for class property which you want to place in dropdown.
Second one is IEnumerable item list.
Third data value field.(Primary key)
Last one is Data text field which you want to display in drop down list.

MVC 4 Session Variable getting updated and I don't know how

I have a method to retrieve session variables, in this case Organizations. For some reason, when I call the get session method the get Organizations and pass the data to a SelectList method to handle some naming logic, the session variable is getting updated. I don't wanted the session values updated and don't understanding what is happening. Below are all the methods. What am I missing?
Controller Method:
public ActionResult Create()
{
SignUpEventFormModel model = new SignUpEventFormModel();
SelectListHelpers listHelper = new SelectListHelpers();
model.OrganizationList = listHelper.GetOrgSelectList(sessionRepository.GetUserSession().Organizations, null);
return View(model);
}
Get User Session Method:
public UserSession GetUserSession()
{
UserSession us = (UserSession)HttpContext.Current.Session["UserSession"];
if (us == null)
{
string email = HttpContext.Current.User.Identity.Name;
SessionSetupRepository sessionsetupRepository = new SessionSetupRepository(new UserRepository(null, null), new SignUpRepository(), new ActivityRepository(), new OrganizationRepository());
us = sessionsetupRepository.SetupUserSession(email);
}
return us;
}
Get Org Select List Method:
public SelectList GetOrgSelectList(IEnumerable<Organization> Orgs, int? SelectedOrgID)
{
List<Organization> OrgList = Orgs.ToList();
OrgList.Where(o => !o.IsAdmin).ToList().ForEach(o => o.Name = o.Name + " (Permission Request Required)");
if (SelectedOrgID.HasValue)
return new SelectList(OrgList, "OrganizationID", "Name", (int)SelectedOrgID);
else
return new SelectList(OrgList, "OrganizationID", "Name");
}
Created a IList parameter and converted the organizations to a list.

How to change the foreign key using ASP.NET MVC 2 + Entity

[HttpPost]
public ActionResult Edit(FormCollection form)
{
// Get movie to update
var id = Int32.Parse(form["id_foto"]);
var fotoToAdd = _db.foto.First(m => m.id_foto == id);
// Deserialize (Include white list!)
TryUpdateModel(fotoToAdd, new string[] { "descricao" }, form.ToValueProvider());
//Here I try to change my foreign key, but i get this exception: "The property 'id_album' part of the key information of the object and can not be changed."
fotoToAdd.id_album = Convert.ToInt32(form["id_album"]);
//file upload
if (Request.Files.Count > 0)
{
int tamanho = (int)Request.Files[0].InputStream.Length;
byte[] arq = new byte[tamanho];
Request.Files[0].InputStream.Read(arq, 0, tamanho);
byte[] arqUp = arq;
fotoToAdd.imagem = arqUp;
}
//Validation
if (String.IsNullOrEmpty(fotoToAdd.descricao))
ModelState.AddModelError("Descrição", "Ops... campo obrigatório");
if (String.IsNullOrEmpty(fotoToAdd.id_album.ToString()))
ModelState.AddModelError("Album", "Ops... campo obrigatório");
if (fotoToAdd.imagem == null)
ModelState.AddModelError("Foto", "Ops... campo obrigatório");
//If success, Update
if (ModelState.IsValid)
{
_db.SaveChanges();
return RedirectToAction("Index");
}
//Else, return view
return View(fotoToAdd);
}
//Here I try to change my foreign key, but i get this exception: "The property 'id_album' part of the key information of the object and can not be changed."
fotoToAdd.id_album = Convert.ToInt32(form["id_album"]);
I have been researching how to do this, but am having difficulty, how do I make this update operation
This will be a help for you
Entity Framework: Setting a Foreign Key Property

Resources