EF - 处理多个映射的正确方法

时间:2016-01-25 16:34:07

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

我有一个包含很多实体的项目,但其中有几个以有趣的方式链接。 UserPurchaseOrder每个都有两个很多关系,以便跟踪1)给定用户是否查看了采购订单,或2)需要收到有关购买更改的警报订购。我使用流畅的EF映射。

其余部分是特定于我的情况的信息,但基本问题是:我应该如何在EF中最好地处理这种设置(两个表之间有两个独立的M:N关系)?

大大简化的图表:

DB diagram

我尝试了下面的代码,但是在调用.Clear()时收到错误。这个错误可能不准确,我已经改变了相当多的代码,因为那时试图解决这个问题。

A relationship from the 'PurchaseOrder' AssociationSet is in the 'Deleted' /
state. Given multiplicity constraints, a corresponding 'User' must also in /
the 'Deleted' state.

如果我尝试使用po.UsersViewed.Add(currentUser)然后_poService.Update(po)添加到列表中,则会出现此错误。 currentUserpo都是从数据库中提取的代理。

An error occurred while saving entities that do not expose foreign key /
properties for their relationships. The EntityEntries property will return /
null because a single entity cannot be identified as the source of the exception.

User上课:

public int Id { get; set; }
public Guid UserGuid { get; set; }
public string Email { get; set; }
public string Password { get; set; }

public virtual ICollection<PurchaseOrder> PurchaseOrdersViewed { get; set; }
public virtual ICollection<PurchaseOrder> PurchaseOrdersAlert { get; set; }

PurchaseOrder上课:

public int Id { get; set; }
public string PONumber { get; set; }

public virtual ICollection<User> UsersViewed { get; set; }
public virtual ICollection<User> UsersAlert { get; set; }

PurchaseOrder流畅映射的相关部分如下。 User映射没有相关的行。

HasMany(s => s.UsersViewed)
    .WithMany(s => s.PurchaseOrdersViewed)
    .Map(cs =>
        {
            cs.MapLeftKey("UserId");
            cs.MapRightKey("PurchaseOrderId");
            cs.ToTable("PurchaseOrderViewed");
        });

    HasMany(s => s.UsersAlert)
        .WithMany(s => s.PurchaseOrdersAlert)
        .Map(cs =>
        {
            cs.MapLeftKey("UserId");
            cs.MapRightKey("PurchaseOrderId");
            cs.ToTable("PurchaseOrderAlert");
        });

这些代码几乎总是调用它们。 po是使用EF从数据库中提取的PurchaseOrder实体的代理。

po.PurchaseOrdersAlert = po.PurchaseOrdersViewed;
po.PurchaseOrdersViewed.Clear();

1 个答案:

答案 0 :(得分:1)

答案实际上取决于您想要收集到名为UserPurchaseOrder关系的实体的数据。对我而言,似乎你对三件事感兴趣。

  1. 如果应首先将采购订单发送给用户。
  2. 如果用户在发送给用户后再查看它。
  3. 如果用户有兴趣接收有关此采购订单的提醒。
  4. 您可以使用标记的枚举

    对此进行建模
    [Flags]
    public enum PurchaseOrderStatus
    {
        None = 0,
        Sent = 1 << 0, // 1
        Received = 1 << 1, // 2
        Enrolled = 1 << 2, // 4
    }
    

    首先,您通过添加status = 1的关系将PO发送给用户,在用户看到发送给他的PO之后,您将状态更改为3(1 + 2)。如果用户有兴趣看到他/她注册的提醒并且状态更新为7(1 + 2 + 4)。