创建复合键实体框架
Posted
技术标签:
【中文标题】创建复合键实体框架【英文标题】:Creating Composite Key Entity Framework 【发布时间】:2013-01-30 03:46:10 【问题描述】:简而言之,我想在保留主键的表上创建复合键,以提高 sql server 搜索性能。每当我搜索没有主键(即 GUID 字符串)的实体时,性能问题就会出现在 200k 数据表上。假设我有 3 个班级
public class Device
public int ID get; set;
public string UDID get; set;
public string ApplicationKey get; set;
public string PlatformKey get; set;
public ICollection<NotificationMessageDevice> DeviceMessages get; set;
public class NotificationMessageDevice
[Column(Order = 0), Key, ForeignKey("NotificationMessage")]
public int NotificationMessage_ID get; set;
[Column(Order = 1), Key, ForeignKey("Device")]
public int Device_ID get; set;
public virtual Device Device get; set;
public virtual NotificationMessage NotificationMessage get; set;
public class NotificationMessage
public int ID get; set;
public string Text get; set;
public DateTime CreateDate get; set;
modelBuilder.Entity<Device>().HasKey(t => new t.ID, t.ApplicationKey, t.PlatformKey, t.UDID );
问题在于,每当我想使用 modelBuilder 将 ID 、 UDID 、 ApplicationKey 和 PlatformKey 定义为复合键时,都会出现以下错误。
NotificationMessageDevice_Device_Target_NotificationMessageDevice_Device_Source: : 依赖角色和主体角色中的属性数量 关系约束必须相同
我认为问题在于 NotificationMessageDevice 上的导航属性无法识别 Device 表上的主键。我该如何解决这个问题?除此之外,如果您分享您提高实体框架搜索性能的经验,我将很高兴。通常,每当我使用不带主键的 First 方法时,都会出现性能问题。
【问题讨论】:
我对 EF 开发不太感兴趣,但你的ForeignKeyAttribute
不是写错了吗?
【参考方案1】:
如果 Device 表有复合主键,那么您的 NotificationMessageDevice 表上需要相同的复合外键。 SQL如何找到没有完整主键的设备?此外,您应该使这些字段成为 NotificationMessageDevice 表主键的一部分。否则你不能保证主键是唯一的:
public class NotificationMessageDevice
[Column(Order = 0), Key, ForeignKey("NotificationMessage")]
public int NotificationMessage_ID get; set;
[Column(Order = 1), Key, ForeignKey("Device")]
public int Device_ID get; set;
[Column(Order = 2), Key, ForeignKey("Device")]
public string Device_UDID get; set;
[Column(Order = 3), Key, ForeignKey("Device")]
public string Device_ApplicationKey get; set;
public virtual Device Device get; set;
public virtual NotificationMessage NotificationMessage get; set;
【讨论】:
每当我们使用设备对象作为导航属性时,我们需要实现复合键上定义的所有属性是否必须在目标表中实现。 是的,这将是数据库中的外键。外键是父表的主键,所以应该完全一样。顺便说一句,如果您希望PlatformKey
成为设备 PK 的一部分,您还需要 NotificationMessageDevice 中的该字段
嗯还有一个问题,那么有没有办法在实体框架上创建超级键?
@kkocabiyik 据我所知,不,没有超级键
@kkocabiyik & SergeyBerezovskiy SQL PK 和 UNIQUE NOT NULL 声明超级键。 PK 的关系含义是您为此选择的某个 CK,而 CK 是不包含更小的 CK 的超级密钥。 SQL 允许声明包含较小值的 PK 或 UNIQUE NOT NULL。以上是关于创建复合键实体框架的主要内容,如果未能解决你的问题,请参考以下文章