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

EF6 and MVC5: Using two fields as a combined key

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

当table全部生成后,EF在更新table中为每个class创建一个FK(Product_ID、Rule_ID等.).这似乎非常低效。我可以使用双字段键,例如 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. 您是否希望存储每个 table 的更新历史记录?如果将其限制为几个 table,您的设计可能会正常工作。但是,如果您想更新许多 table,您可能想尝试以下选项。
  2. 包括 3 tables(产品、更新和 ProductUpdates)。 Products tables 将始终具有最新数据。每次更新 Products 中的条目时,Updates tables 将获得一个新行来捕获更新的时间戳。 ProductUpdates 将有一个指向 Updates table 的外键,并且会有来自 Products table 的旧行。这样您就可以确切地知道该行在任何时间点的内容。将其扩展到任何其他 table X 将需要添加 XUpdates table。但是你不会有你提到的不必要的 50 个外键。
  3. 另一种选择是在 table 中添加 IsActive、UpdatedBy、UpdatedTimestamp 等列。每次更新一行时,将其标记为不活动并插入包含最新数据的新行。如果需要,您还可以存储原因和规则列。
  4. 您还可以重新设计您的实体,使其主键成为更新的外键 table。这样您将消除所有先前解决方案的不雅之处。每次更新时,您都会在 Updates table 中插入一行,并使用生成的 Id 作为产品中新行的主键 table.
  5. Entity Framework 可以帮助您自动化第 3 点和第 4 点中列出的过程。基本思想是拦截更新的保存请求并强制执行更新和插入。
  6. 最后,您还可以使用 CLR 触发器来获得所需的审计功能。

每种解决方案都有其优点和缺点。最适合您的解决方案取决于您的具体用例。