EF4.1:如何处理添加到对象中的项目';的收藏

本文关键字:对象 项目 收藏 添加 何处理 处理 EF4 | 更新日期: 2023-09-27 17:59:41

我是第一次使用EF4.1(请耐心等待),但我无法理解如何将新项目添加到对象的子集合中,然后保存对象。

例如,对于下面的类,我最初可以将TravelTicket(包含多个人)保存到我的数据库中,但一旦我添加了一个新人,然后再次尝试保存TravelTickets,我就会得到:

ObjectStateManager中已存在具有相同键的对象。ObjectStateManager无法跟踪具有相同键的多个对象。

有人能帮忙吗?

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; }
}

数据库上下文:

public class TicketContext : DbContext
{
    public TicketContext()
        : base("TicketStore")
    { }
    public DbSet<TravelTicket> TravelTickets { get; set; }
    public DbSet<Person> People { get; set; }
}

存储库(仅限相关方法):

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控制器代码:

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();
    }
}

对"Next"方法的调用"ticketResetory.InsertOrUpdate(ticket);"导致异常:

ObjectStateManager中已存在具有相同键的对象。ObjectStateManager无法跟踪具有相同键的多个对象

进一步编辑:如果我在保存对象后将其从数据库中拉回来,而不是从会话中拉对象,那么添加2个新人就可以了:

作品:TravelTicket ticket=ticketResetory.Find(ticketId);票Members.Add(新人{Name="Peter"});票Members.Add(新人{Name="Paul"});ticketResetory.InsertOrUpdate(ticket);ticketPosition.Save();

不起作用:TravelTicket ticket=(TravelTicket)会话["ticket"];票Members.Add(新人{Name="Peter"});票Members.Add(新人{Name="Paul"});ticketResetory.InsertOrUpdate(ticket);ticketPosition.Save();

EF4.1:如何处理添加到对象中的项目';的收藏

我需要查看您用于添加项并持久化它们的代码。在此之前,请提供一些一般性建议。

你似乎在用一个长寿的环境来做你的事情。这是一个很好的做法,使用短期生存环境,如:

  • 实例上下文
  • 执行单个操作
  • 处理上下文

冲洗并重复你必须做的每一个操作。在遵循这个好的做法的同时,你可以间接地解决你的问题。

同样,要获得更具体的帮助,请发布您正在使用的代码;)

在您的person映射类中,您可能需要执行类似的操作

 Property(p => p.Id)
            .StoreGeneratedPattern = StoreGeneratedPattern.Identity;