【问题标题】: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 不是写错了吗?

标签: c# entity-framework entity-framework-5 composite-key


【解决方案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。
猜你喜欢
  • 2015-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多