Asp.net mvc 5 EF6和MVC5:使用两个字段作为组合键

Asp.net mvc 5 EF6和MVC5:使用两个字段作为组合键,asp.net-mvc-5,entity-framework-6,Asp.net Mvc 5,Entity Framework 6,我有几个对象(产品、规则、价格细节等)在CRUD应用程序中管理和存储信息。我想要一种保存数据更新日志的方法,为此,我创建了一个更新类,在每个数据类中引用为ICollection Updates 当所有表都生成时,EF为更新表中的每个类(产品ID、规则ID等)创建一个FK。这似乎效率极低。我是否可以使用双字段键,例如enum ObjectType和long ID?或者,我可以使用字符串ID并强制使用一个模式,其中字符串的前N个字符标识引用对象吗?如果是后者,数据库能否自动递增字符串值 以下是一些示

我有几个对象(产品、规则、价格细节等)在CRUD应用程序中管理和存储信息。我想要一种保存数据更新日志的方法,为此,我创建了一个更新类,在每个数据类中引用为
ICollection Updates

当所有表都生成时,EF为更新表中的每个类(产品ID、规则ID等)创建一个FK。这似乎效率极低。我是否可以使用双字段键,例如
enum ObjectType
long ID
?或者,我可以使用
字符串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; }
}
公共类更新
{
[数据库生成(DatabaseGeneratedOption.Identity)]
公共长ID{get;set;}
公共字符串原因{get;set;}
public DateTime TimeOfUpdate{get;set;}
公共长乘积_ID{get;set;}
公共长规则_ID{get;set;}
}
公共类产品
{
[数据库生成(DatabaseGeneratedOption.Identity)]
公共长ID{get;set;}
公共字符串名称{get;set;}
公共价格详细信息价格{get;set;}
公共ICollection更新{get;set;}
}
公共阶级规则
{
[数据库生成(DatabaseGeneratedOption.Identity)]
公共长ID{get;set;}
公共字符串名称{get;set;}
公共ICollection条件{get;set;}
公共ICollection更新{get;set;}
}

处理审核逻辑有多种方法

  • 您是否希望存储每个表的更新历史记录?如果只限于几个表,您的设计可能会很好。但是,如果要更新多个表,可能需要尝试以下选项
  • 包括3个表(产品、更新和产品更新)。产品表将始终包含最新数据。每次更新产品中的条目时,更新表将获得一个新行,该行捕获更新的时间戳。ProductUpdates将具有更新表的外键,并且将具有Products表中的旧行。通过这种方式,您可以准确地知道该行在任何时间点的外观。将其扩展到任何其他表X将需要添加xUpdate表。但是你不会有你提到的不必要的50个外键
  • 另一个选择是让IsActive、UpdatedBy、updatetimestamp等。。。表中要更新的列。每次更新一行时,都会将其标记为非活动,并插入包含最新数据的新行。如果需要,还可以存储原因和规则列
  • 您还可以重新设计实体,使其主键是更新表的外键。这样,您将消除以前所有解决方案的不美观。每次更新时,都会在更新表中插入一行,并将生成的Id用作products表中新行的主键
  • 实体框架可以帮助您自动化第3点和第4点中列出的流程。基本思想是拦截更新的保存请求,并强制更新和插入
  • 最后,您还可以使用CLR触发器来实现所需的审核功能
  • 每种解决方案都有其优缺点。您的最佳解决方案取决于您的特定用例

    为什么它“效率极低”?也许不是,但似乎是这样。如果我最终有50个类在编写更新,那么数据库中就需要50个FK列,其中大多数没有任何数据。对我来说,这听起来不是精心设计的。