EF6和MVC5:使用两个字段作为组合键

时间:2015-01-28 18:18:41

标签: asp.net-mvc-5 entity-framework-6

我有几个对象(Product,Rule,PriceDetail等),用于管理和存储CRUD应用程序中的信息。我想要一种方法来记录数据更新的时间,为此我创建了一个Update类,在每个数据类中引用为ICollection<Update> Updates

当所有表都生成时,EF会在Updates表(Product_ID,Rule_ID等)中为每个类创建一个FK。这似乎非常低效。我可以使用双字段密钥,例如enum ObjectTypelong ID吗?或者,我可以使用string ID并强制一个模式,其中字符串的前N个字符标识引用对象吗?如果是后者,数据库可以自动递增字符串值吗?

以下是一些示例代码,已在此处进行裁剪:

public class Update
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long ID { get; set; }
    public string Reason { get; set; }
    public DateTime TimeOfUpdate { get; set; }
    public long Product_ID { get; set; }
    public long Rule_ID { get; set; }
}

public class Product
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long ID { get; set; }
    public string Name { get; set; }
    public PriceDetail Price { get; set; }
    public ICollection<Update> Updates { get; set; }
}

public class Rule
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long ID { get; set; }
    public string Name { get; set; }
    public ICollection<Condition> Conditions { get; set; }
    public ICollection<Update> Updates { get; set; }
}

1 个答案:

答案 0 :(得分:0)

处理审计逻辑有多种方法。

  1. 您是否预计会存储每张桌子的更新历史记录?如果它仅限于几张桌子,你的设计可能会正常工作。但是,如果要更新许多表,可能需要尝试以下选项。
  2. 包括3个表(产品,更新和ProductUpdates)。 Products表将始终包含最新数据。每次更新Products中的条目时,Updates表将获得一个新行,捕获更新的时间戳。 ProductUpdates将具有Updates表的外键,并且将具有Products表中的旧行。通过这种方式,您可以准确地知道行在任何时间点的位置。将其扩展到任何其他表X将需要添加XUpdates表。但你不会有你提到的不必要的50个外键。
  3. 另一种选择是在表中更新IsActive,UpdatedBy,UpdatedTimestamp等列。每次更新一行时,都会将其标记为非活动状态,并插入包含最新数据的新行。如果需要,您还可以存储原因和规则列。
  4. 您还可以重新设计实体,使其主键是更新表的外键。这样您就可以消除以前所有解决方案的不雅。每次更新时,都会在Updates表中插入一行,并使用生成的Id作为products表中新行的主键。
  5. 实体框架可以帮助您自动化第3点和第4点中列出的流程。基本思路是拦截保存更新请求并强制更新并插入。
  6. 最后,您可能还可以使用CLR触发器来获得所需的审核功能。
  7. 每种解决方案都有其优点和缺点。最适合您的解决方案取决于您的具体用例。