EF4.1:如何处理项目被添加到一个对象的集合 [英] EF4.1 : How to deal with items being added to an Object's collection

查看:597
本文介绍了EF4.1:如何处理项目被添加到一个对象的集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆