0

尝试添加具有非新对象/实体图的新实体时遇到问题。

这是我使用 Code First 方法的域类型:

public class Person : IEntity
{
   public int Id { get; set; }
   public string Name { get; set; }
   public List<PersonSession> Sessions { get; set; }
}

 public class PersonSession : IEntity
 {
    public int Id { get; set; }
    public Person Person { get; set; }
    public Session Session { get; set; }
 }

public class Session : IEntity
{
  public int Id { get; set; }
  public string Title { get; set; }     
}

所以我有一个人,他们可以有很多会话,并且会有一个他们的会话表。Session 表虽然不会对人员有任何引用,但这就是 PersonSessions 表/关系的用途。

EF 5 确实使用一个 DbSet 创建了这 3 个表。

但是我正在尝试使用泛型制作一个简单的存储库模式,并且我有一个 Save 方法。

唯一的问题是,即使我使用 Repository.GetAll(); 提供给我的现有会话,它也会向 Sessions 表添加一个新会话;

 public int Save(T t)
 {
    if (t.Id == 0)
       _context.Entry(t).State = EntityState.Added;
    else
       _context.Entry(t).State = EntityState.Modified;

    _context.SaveChanges();
    return t.Id;
 }

因此,当我创建 2 个新会话,然后通过 Sessions 的 Generic Repo 实例添加它们时,它们会被正确添加,

当我尝试创建一个新人并给他那些现有的会话时:

  private static void AddPerson()
  {

     var newPerson = new Person
                        {
                           JobTitle = EJobTitle.SoftwareDeveloper,
                           Name = "Mark W",
                        };

     var sessionsForPerson = new List<PersonSession>();

     var session1 = _sessionRepo.Retrieve(1);
     var session2 = _sessionRepo.Retrieve(2);

     sessionsForPerson.Add(new PersonSession
                              {
                                 Session = session1,
                                 Person = newPerson
                              });

     sessionsForPerson.Add(new PersonSession
                              {
                                 Session = session2,
                                 Person = newPerson,
                              });

     newPerson.Sessions = sessionsForPerson;

     _personRepo.Save(newPerson);
  }

它正在第二次添加会话。

是否有一个数据属性可以放在 PersonSession.Session 属性上,告诉它这将始终是一个现有会话,还是我需要在 FluentApi 中使用某些东西来指示 EF?

谢谢。

4

2 回答 2

1

在您的Save方法中,您将 new 的状态设置PersonEntityState.Added. 当您这样做时,EF 将对象图中每个对象的状态设置为AddedSessions 已经具有 > 0 的 Id并不重要。除非图中的对象先前由相同的上下文检索过。在这种情况下,它们将保持不变(并且只会保存关联)。

所以这就是问题所在。您的每个存储库都有自己的上下文。这是通用存储库的常见问题。一种可能的补救措施是在存储库之外创建一个上下文并将其注入到一个业务事务中涉及的存储库中。另一种是在添加根实体后通过遍历对象图来确保现有对象以未修改状态进入上下文。

于 2012-12-19T22:40:43.637 回答
0

尝试指定哪些属性是您的实体键:

public class Person : IEntity
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public List<PersonSession> Sessions { get; set; }
}

 public class PersonSession : IEntity
 {
    [Key]
    public int Id { get; set; }
    public Person Person { get; set; }
    public Session Session { get; set; }
 }

public class Session : IEntity
{ 
    [Key]
    public int Id { get; set; }
    public string Title { get; set; }     
}
于 2012-12-19T21:46:53.530 回答