代码之家  ›  专栏  ›  技术社区  ›  Dan Morphis

实体框架代码第一个多对多创建重复行

  •  8
  • Dan Morphis  · 技术社区  · 15 年前

    结果发现我的问题有两个上下文,我重新编写了一点代码,使其只有一个上下文,我的问题就消失了。

    我有一个用户有一个UserContact的列表,它本身有一个ContactOption。这是一个相当简单的1对多,多到1,中间的用户接触表。

    如果我把用户从数据库中拉出来并创建一个新的用户联系,但是将一个现有的项目(我从数据库中拔出)设置了触碰,当我保存更改时,实体框架在数据库中创建了一个新的触控,它本质上是我添加到用户触发器的一个副本(除了它得到一个新的ID)。

    我已经和这个斗争了好几个小时,但还是搞不清楚。有什么想法吗?

    我正在使用存储库模式进行数据库查询,但我已确保它们共享相同的上下文。

    我使用以下命令将用户从数据库中拉出:

    var user = _context.Users.Include("UserContacts.ContactOption")
                  .Where(id => id == 1);
    

    以及联系人选项:

    var co = _context.ContactOptions.FirstOrDefault(c => c.Id == id);
    

    我将ContactOption添加到UserContact,如下所示:

    var contactOption = _context.ContactOptions.FirstOrDefault(c => c.Id == someId);
    
    var contact = new UserContact { ContactOption = contactOption  };
    contact.Data = "someData";
    
    user.UserContacts.Add(contact);
    

    我的模型是这样的:

    public class User
    {
        [Key]
        public int Id { get; set; }
    
        public virtual ICollection<UserContact> UserContacts { get; set; }
    }
    
    public class UserContact
    {
        [Key]
        public int Id { get; set; }
    
        [Required]
        public User User { get; set; }
    
        [Required]
        public ContactOption ContactOption { get; set; }
        public string Data { get; set; }
    }
    
    public class ContactOption
    {
        [Key]
        public int Id { get; set; }
        public string Name { get; set; }
    }
    
    2 回复  |  直到 15 年前
        1
  •  2
  •   Morteza Manavi    15 年前

    我运行了你的代码,得到了准确的预期结果:新的一行 用户联系人 表中包含了现有的USER ID和CONTACTACTIOID,所以我不确定里面发生了什么,但是您可以尝试在用户联系对象中显式地使用FKS,这样您就可以完全控制代码是如何为您插入记录的。为此,您需要按如下方式更改用户联系人:

    public class UserContact
    {
        public int Id { get; set; }
    
        // By Convention these 2 properties will be picked up as the FKs: 
        public int UserId { get; set; }
        public int ContactOptionId { get; set; }
    
        [Required]
        public User User { get; set; }        
        [Required]
        public ContactOption ContactOption { get; set; }
    
        public string Data { get; set; }
    }
    

    然后您可以这样更改代码:

    var contactOption = _context.ContactOptions.Find(someId);
    var user = _context.Users.Find(1);
    
    var contact = new UserContact 
    { 
        ContactOptionId = contactOption.Id,  
        UserId = user.Id,
        Data = "someData"
    };
    
    user.UserContacts.Add(contact);
    context.SaveChanges();
    
        2
  •  1
  •   Dan Morphis    15 年前

    结果发现我的问题有两个上下文,我重新编写了一点代码,使其只有一个上下文,我的问题就消失了。感谢莫泰萨·马纳维给我指出了正确的方向。