2013-02-14 123 views
52

不久,我想在我的表上创建组合键与主键,以提高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 }); 

的问题是什么,每当我想要的ID,UDID,ApplicationKey和PlatformKey定义为复合键与模型构建器它提供了以下错误。

NotificationMessageDevice_Device_Target_NotificationMessageDevice_Device_Source: :在一个 关系约束的依赖和主要角色的属性数必须相同

我认为这个问题是因为NotificationMessageDevice导航性能是无法识别Device表上的主键是什么。我该如何解决这个问题?除此之外,如果您分享改善Entity框架搜索性能的经验,我会很高兴。通常,无论何时使用没有主键的First方法,性能问题都会发生。

+0

我对EF开发并没有太多的想法,但是你没有'ForeignKeyAttribute'对错误的东西? – 2013-02-14 10:55:46

+1

Nop这是正确:) – kkocabiyik 2013-02-14 10:58:05

回答

73

如果设备表有复合主键,那么你需要在你的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; } 
} 
+0

这是我们需要实现的所有组合键上定义的属性必须在目标表上实现,只要我们使用Device对象作为导航属性。 – kkocabiyik 2013-02-14 11:18:50

+0

是的,这将是数据库中的外键。外键是来自父表的主键,所以它应该完全相同。顺便说一句,如果你想'PlatformKey'是设备PK的一部分,你还需要NotificationMessageDevice中的该字段也是 – 2013-02-14 11:20:24

+0

嗯,还有一个问题,有没有什么办法在Entity Framework上创建超级密钥呢? – kkocabiyik 2013-02-14 11:28:01