我有一个表DataSourceDefinition,用于存储有关不同类型数据源的信息。由于每个数据源自然都分配了GUID,因此我将其用作主键。
每种数据源类型都有某些编号为1,2的设置...... 我想在第二个表DataSourceSettingDefinition中存储有关这些设置的信息(Name,Datatype,EditorType ...)。我认为使用由数据源类型的唯一GUID组成的复合键是自然的,后者将是外键,而Integer 1,2 ...(SettingID)在给定数据源中是唯一的类型。两者的结合总是独一无二的。
当我尝试使用以下键插入两个数据源设置定义时:
DataSourceDefinitionID - SettingID
5E880F15-80CA-45EC-AD5A-6D406B06AB08 - 1
5E880F15-80CA-45EC-AD5A-6D406B06AB08 - 2
我收到以下错误:
System.Data.SqlClient.SqlException: Violation of UNIQUE KEY
constraint 'AK_DataSourceSettingDefinition_DataSourceDefinitionID'. Cannot
insert duplicate key in object 'dbo.DataSourceSettingDefinition'. The
duplicate key value is (5e880f15-80ca-45ec-ad5a-6d406b06ab08). at ...
为什么这不可能?
以下是我的代码优先模型:
public class DataSourceDefinition
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid ID { get; set; }
[Required]
[StringLength(50)]
public string NameEn { get; set; }
[StringLength(300)]
public string DescriptionEn { get; set; }
...
}
public class DataSourceSettingDefinition
{
[Key, Column(Order = 1)]
public Guid DataSourceDefinitionID { get; set; }
[Key, Column(Order = 2)]
public int SettingID { get; set; }
[Required]
[StringLength(50)]
public string NameEn { get; set; }
[StringLength(300)]
public string DescriptionEn { get; set; }
[Required]
public int DataType { get; set; }
...
}
更新
我忘了在我的OnModelCreating中显示代码。 EF7文档的预发布版本说明
您仍然可以向实体类添加注释,以便其他框架(例如ASP.NET MVC)使用它们,但实体框架不会处理这些注释。
这就是为什么我将数据注释留在原地并添加以下内容
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<DataSourceSettingDefinition>().Key(m => new { m.DataSourceDefinitionID, m.SettingID });
}
答案 0 :(得分:0)
事实证明,这些声明中的数据注释存在问题:
[Key, Column(Order = 1)]
public Guid DataSourceDefinitionID { get; set; }
[Key, Column(Order = 2)]
public int SettingID { get; set; }
如果我删除数据注释并将主键构建单独保留在流畅的API中,它将按预期工作。尽管预发布文档说EF7不会处理数据注释,但仍然存在副作用。有了数据注释,似乎生成了主键和备用键,但不是复合键。在这种情况下,插入两个具有相同GUID的DataSourceSettingDefinition当然必须失败。
答案 1 :(得分:0)
在EF 7中
无法使用数据注释配置唯一约束。您必须使用流畅的API来配置它。
如何配置
class MyContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Employee>()
.HasAlternateKey(e => e.EmployeeCode)
.HasName("AlteranteKey_EmployeeCode");
}
}
class Employee
{
[Key]
public int EmployeeId { get; set; }
public string Name { get; set; }
public string EmployeeCode { get; set; }
public DateTime DateOfBirth { get; set; }
}