EF在多对多表中插入重复记录

时间:2014-02-19 20:05:00

标签: c# asp.net-mvc entity-framework many-to-many

我很担心这个。

我读了很多文章,如:

Entity Framework adding record into many to many mapping table

我的情况符合这些文章中描述的内容。从本质上讲,我有一个典型的多对多场景。我有一个客户表,一个固定的地址表和CustomerFixedAddress。您可能猜测CustomerFixedAddress表是两列。 CustomerId和FixedAddressId。

只是为了理解固定地址是用户选择的预先限定地址列表。

我的问题是我不理解文章中的内容,因为我的努力仍然导致记录被输入两个表格。

我最近的一次尝试是从其中一篇文章开始,使用一个对象作为现有记录的副本/副本。 (我的错误假设是,EF会认识到现有记录而不是创建新记录)

我不知道这是问题的一部分,但我想知道我的映射是否不正确所以这里是CustomerMap:

this.HasMany<FixedAddress>(ef => ef.FixedAddress)
    .WithMany()
    .Map(m => m.ToTable("Customer_FixedAddress")
    .MapLeftKey("Customer_Id").MapRightKey("FixedAddress_Id"));

基本上这就是我的工作:

//This line passes the id of user selected address record to our address service
//which returns an object that is exactly the record I want the relationship pointing to
FixedAddress FxdAddy = _addyService.GetFixedAddressesById(model.FixedAddyId);

//So here I am adding the addy record to the customer object
customer.FixedAddresses.Add(FxdAddy);

结果是我的Customer表不受影响。 我的FixedAddress表插入了一条新记录....这是用户选择的现有记录的伪造。

我的CustomerFixedAddress表有一个正确且不正确的新条目。正确填充了customerid列。 fixedaddress列已正确填充插入的 NEW 欺骗记录的ID。

这不是我想要的。应该插入记录的唯一表是CustomerFixedAddress表...显然,新记录将在相应表中具有 EXISTING 记录的正确customerid和fixedaddressid。

所以我有点理解如何将dupe添加到fixedaddy表中......我已将其添加到客户对象中,然后从那个角度更新所有内容......但我不知道如何以不同方式执行得到我想要的结果???

谢谢


@slauma这个项目是由知识渊博的人开发的,所以我为黑客攻击道歉。

在addy服务中我只是启动了一些LINQ:

public FixedAddress GetFixedAddressesById(int FxdAddyId)
{
  FixedAddress FxdAddy = new FixedAddress();

  var query = _addressFixedAddressRepository.Table
            .Where(efb => efb.Id == FxdAddyId)
            .Select(...removed save space);
        foreach (var item in query)
        {...removed save space }

        return FxdAddy;
 }

现在我认为后续将是_addressFixedAddressRepository?

的上下文

它被定义为类宽:

private readonly IRepository<FixedAddress> _addressFixedAddressRepository;

并在构造函数中生成,然后在其中传递,然后在本地分配.....客户对象也是如此。

我应该更新addyservice中的客户对象吗?我说这只是猜测客户对象在从控制器访问时处于不同的上下文中。(我现在正在做什么)因此从服务中返回的内容是不同的。


好的,我在服务中找到了

private readonly IDbContext _context;

当然它是在构造函数上注入的。

1 个答案:

答案 0 :(得分:1)

首先,我要感谢Jim Wooley和Slauma。你最有帮助让我开始朝着正确的方向前进。根据您的评论,我能够更好地优化我的Google搜索。例如,Slauma表示它是一个存储库/服务架构。好吧,我有更好的谷歌搜索条件,知道要阅读什么,从而解决了这个问题。

其次,我对没有提供技术解释表示歉意。我要告诉别人我做了哪些不同的事情,但不可否认,我仍然不完全理解EF在封面下执行的内容/方式,所以这个答案是我粗略的理解草案。

我将重复这个场景,但是为了实现看看OP。我有两个表,然后是他们的映射表。例如,客户表和固定地址表。映射表将客户和固定地址放在一起。

过去我通过创建地址对象并将其添加到上下文来完成此操作。这很好,因为地址记录需要添加到地址表中AS作为customeraddress表中的映射条目。

然而,在我不想在fixedaddress表中输入的情况下,我还是得到了一个。

我最终做的是在映射表中添加ID列。我创建了映射表的实体表示...注意需要一个属性来保存要映射的对象。

public virtual int CustomerId { get; set; }
public virtual int FixedAddressId { get; set; }
public virtual Customer Customer { get; set; } //note this property is NOT in the DB
public virtual FixedAddress FixedAddress { get; set; } //note this property is NOT in the DB

然后我也改变了我的映射:

this.ToTable("Customer_FixedAddress");
this.HasKey(pc => pc.Id);

this.HasRequired(pc => pc.Customer)
.WithMany(p => p.FixedAddress) //this is an ICollection on the customer object
.HasForeignKey(pc => pc.CustomerId);

this.HasRequired(pc => pc.FixedAddress)
.WithMany()
.HasForeignKey(pc => pc.FixedAddressId);

当然,我必须使用这些更改对服务和控制器中的代码进行一些清理,但是一旦我完成了正确插入的记录,一切都很顺利。

再次感谢您的帮助。