I know that it seems a duplicate entry, but I red all the posts related with my problem and I can't find the solution. I'm stuck with this problem about one week. Maybe I have made some design problem or I don't know. The problem is I can't update a navigation property, I tried several options, everytime i got a different error or a duplicate. Ok, here's the scenario:
I have an object "List"
int ID string Name int SendType Category category //these are navigation property Product product //these are navigation property
Category and Product don't know about the relation with List. I use POCO classes generated by the CTP5 DbContext Generator Template and I use a repository for every entity. In each repository there's a reference to the dbcontext.
And this is the controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(int id, List list)
{
if (!ModelState.IsValid)
return View(list);
List originalList = this._listRepository.Get(id);
TryUpdateModel(originalList, "List", new string[] { "Name", "SendType"});
//Here's I tried to update manually like this
if (list.category.id != originalList.category.id)
{
Category category = this._categoryRepository.GetNoTracking(list.category.id);
originalList.Category = category;
}
if (list.product.id != originalList.product.id)
{
Product product = this._productRepository.GetNoTracking(list.product.id);
originalList.Product = product;
}
this._listRepository.Save(); //Here's I call only the SubmitChanges()
return RedirectToAction("Index");
}
If I try directly I receive the error
The entity type 'DbEntityEntry' is not part of the model for the current context
because I modify the state of the entity Category or product(they are from another context)
If I submit the changes, without modifying the association, I receive the error
'IDCategory' is a reference key and cannot be updated
And so on......Any suggest will be appreciated, I can also modify the viewmodel if I'm wrong.I'm without ideas! Thanks
UPDATE
//This is in List Repository
public override void Save()
{
checkReferencies();
db.SaveChanges();
}
private void checkReferencies()
开发者_开发技巧 {
foreach (var entry in db.ChangeTracker.Entries()
.Where(e => e.State == EntityState.Modified || e.State == EntityState.Added))
{
if (ObjectContext.GetObjectType(entry.Entity.GetType()).Name.Equals("List"))
{
/*In this case I tried to update my object directly with the object that comes form the form
if (entry.CurrentValues.GetValue<int>("IDList").ToString() != "0" )
{
db.Entry(entry.Entity).State = EntityState.Modified;
} */
if (((List)entry.Entity).Product != null)
{
db.Entry(((List)entry.Entity).Product).State = EntityState.Unchanged;
}
if (((List)entry.Entity).Category != null)
{
db.Entry(((List)entry.Entity).Category).State = EntityState.Unchanged;
}
}
else if (ObjectContext.GetObjectType(entry.Entity.GetType()).Name.Equals("Product")
|| ObjectContext.GetObjectType(entry.Entity.GetType()).Name.Equals("Category"))
{
//here I attach the entry that I added
db.Category.Attach((Category)db.Entry(entry).Entity.Entity);
}
}
}
//This is in categoryRepository
public Category GetNoTracking(int id)
{
return db.Category.AsNoTracking().Single(l => l.IDCategory == id);
}
//This is in productRepository
public Product GetNoTracking(int id)
{
return db.Product.AsNoTracking().Single(l => l.IDProduct == id);
}
//This is my DbContext
namespace BusinessManagerEmail.Models
{
using System;
using System.Data.Entity;
public partial class DBMailMarketingEntities : DbContext
{
public DBMailMarketingEntities()
: base("name=DBMailMarketingEntities")
{
}
public DbSet<Category> Category { get; set; }
public DbSet<Customer> Customer { get; set; }
public DbSet<Subscription> Subscription { get; set; }
public DbSet<List> List { get; set; }
public DbSet<Product> Product { get; set; }
}
}
This is all the code involved. Thanks!
Remove checkReferencies
because:
List
in your example is not modified so the first part of the method will not be executed.- The
Product
cannot be converted toCategory
and attached toDbSet
. It will throw exception. Category
is already attached in Addes state (which is wrong because it will insert category again). Attaching entity again will throw the exception.
Just attach both Category
and Product
to context from listRepository
before you set them in List
.
Or better completely rewrite your code and share context among repostiories.
精彩评论