EF4.1:如何处理项目被添加到一个对象的集合 [英] EF4.1 : How to deal with items being added to an Object's collection
问题描述
我使用EF4.1首次(所以要有耐心与我),但我只是无法得到认真处理我怎么能添加新项目对象的一个子集,然后保存对象。
I'm using EF4.1 for the first time (so be patient with me) but I just cant get to grips with how I can add new items to a sub collection of an object and then save the object.
例如,下面的类,我可以先保存TravelTicket(包含多个人)到我的数据库,但只要我添加了一个新的人物,然后尝试保存在TravelTicket再次获得:
For example, with the classes below, I can initially save the TravelTicket (containing multiple People) into my database, but as soon as I add a new person and then try to save the TravelTicket again I get:
具有相同键的对象已经存在于ObjectStateManager。该ObjectStateManager无法跟踪使用相同的密钥多个对象。
An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.
谁能帮助?
public class TravelTicket
{
public int Id { get; set; }
public string Destination { get; set; }
public virtual List<Person> Members { get; set; }
}
public class Person
{
public int Id { get; set; }
public string Name{ get; set; }
}
编辑:所有相关的代码添加的要求:
领域模型:
public class TravelTicket
{
public int Id { get; set; }
public string Destination { get; set; }
public virtual ICollection<Person> Members { get; set; }
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
的DB上下文:
public class TicketContext : DbContext
{
public TicketContext()
: base("TicketStore")
{ }
public DbSet<TravelTicket> TravelTickets { get; set; }
public DbSet<Person> People { get; set; }
}
存储库(相关方法只):
The Repository (relevant methods only):
public class TicketRepository : ITicketRepository
{
TicketContext context = new TicketContext();
public void InsertOrUpdate(TravelTicket quoteContainer)
{
if (quoteContainer.Id == default(int))
{
// New entity
context.TravelTickets.Add(quoteContainer);
}
else
{
// Existing entity
context.Entry(quoteContainer).State = EntityState.Modified;
}
}
public void Save()
{
try
{
context.SaveChanges();
}
catch (DbEntityValidationException dbEx)
{
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
}
}
}
}
}
public interface ITicketRepository
{
void InsertOrUpdate(TravelTicket travelTicket);
void Save();
}
消费(例如)MVC控制器代码:
The consuming (example) MVC Controller code:
public class TicketSaleController : Controller
{
private readonly ITicketRepository ticketRepository;
public TicketSaleController()
: this(new TicketRepository())
{
}
public TicketSaleController(ITicketRepository ticketRepository)
{
this.ticketRepository = ticketRepository;
}
public ActionResult Index()
{
TravelTicket ticket = new TravelTicket();
ticket.Destination = "USA";
List<Person> travellers = new List<Person>();
travellers.Add(new Person { Name = "Tom" });
travellers.Add(new Person { Name = "Dick" });
travellers.Add(new Person { Name = "Harry" });
ticket.Members = travellers;
ticketRepository.InsertOrUpdate(ticket);
ticketRepository.Save();
Session["Ticket"] = ticket;
return RedirectToAction("Next");
}
public ActionResult Next()
{
TravelTicket ticket = (TravelTicket)Session["Ticket"];
ticket.Members.Add(new Person { Name = "Peter" });
ticket.Members.Add(new Person { Name = "Paul" });
ticketRepository.InsertOrUpdate(ticket);
ticketRepository.Save();
return View();
}
}
调用ticketRepository.InsertOrUpdate(门票); 下一步的方法会导致异常:
The call "ticketRepository.InsertOrUpdate(ticket);" on the "Next" method causes the exception:
具有相同键的对象已经存在于ObjectStateManager。该ObjectStateManager不能用相同的密钥跟踪多个对象
进一步编辑:如果我拉的对象从数据库返回的它被保存,而不是拉后从会话对象,增加了2个新的人工作确定:
FURTHER If I pull the object back from the database after its been saved instead of pulling the object from the session, adding the 2 new persons works OK:
使用:
TravelTicket票= ticketRepository.Find(ticketId);
ticket.Members.Add(新的Person {名称=彼得});
ticket.Members.Add(新的Person {名称=保罗});
ticketRepository.InsertOrUpdate(票);
ticketRepository.Save();
Works: TravelTicket ticket = ticketRepository.Find(ticketId); ticket.Members.Add(new Person { Name = "Peter" }); ticket.Members.Add(new Person { Name = "Paul" }); ticketRepository.InsertOrUpdate(ticket); ticketRepository.Save();
不工作:
TravelTicket票=(TravelTicket)会议[门票];
ticket.Members.Add(新的Person {名称=彼得});
ticket.Members.Add(新的Person {名称=保罗});
ticketRepository.InsertOrUpdate(票);
ticketRepository.Save();
Doesn't Work: TravelTicket ticket = (TravelTicket)Session["Ticket"]; ticket.Members.Add(new Person { Name = "Peter" }); ticket.Members.Add(new Person { Name = "Paul" }); ticketRepository.InsertOrUpdate(ticket); ticketRepository.Save();
推荐答案
我需要查看正在使用添加项目的代码,然后坚持他们。在此之前,一些一般的建议。
I'd need to see the code you are using to add items and then persist them. Until that a few generic advice.
好像你用一个长期生活方面做你的东西。这是一个很好的做法,使用短的生活背景下,像这样的:
It seems like you're using a long-living context to do your stuff. It's a good practice to use short living context, like this:
- 实例上下文
- 请一单人操作
- 处置上下文
冲洗,重复你所要做的每一项操作。虽然按照本很好的做法,可能会间接地解决你的问题。
Rinse and repeat for every operation you have to do. While following this good practice, you could be indirectly solving your problem.
此外,对于更具体的帮助,请发表您使用的代码;)
Again, for more specific help, please post the code you're using ;)
这篇关于EF4.1:如何处理项目被添加到一个对象的集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!