CLARIFICATION:我不是試圖在數據庫字段中存儲類/類型,或者使用類/類型本身作爲鍵值。我試圖使用類/類型(在這種情況下,Guid)的單個屬性作爲關鍵。實體框架6-將主鍵作爲類型的屬性
雖然我不認爲它與這個特定問題嚴格相關,但它可能對上下文有用:我試圖在我的最新項目中實現Semantic Types。我在我的代碼中取得了一些成功,並且事實上確定了幾個可能因此而不快速識別的錯誤。
在一些Fluent API代碼的幫助下,我的語義類型與EF6在非關鍵字字段中整合在一起。
但是,當試圖對關鍵字段使用語義類型時,EF會生成一個運行時異常,指出沒有定義的鍵 - 顯然存在。
用一個簡單的GUID作爲關鍵
這裏是我使用的EF實體不使用語義類型的例子:
public partial class MyEntity
{
[Key]
public Guid id { get; set; }
public string SomeData { get; set; }
}
上述工作正常。
與一類性質的關鍵 - 嘗試#1
現在,我定義了一個新的語義類型,如下所示:
public class MyEntityId: SemanticType<Guid>
{
public MyEntityId()
: base(IsValid, Guid.Empty)
{ }
public MyEntityId(Guid value)
: base(IsValid, value)
{ }
public static bool IsValid(Guid value)
{
return true;
}
}
...並相應地更新EF模型。
public partial class MyEntity
{
[Key]
public MyEntityId id { get; set; }
public string SomeData { get; set; }
}
我再添加一些代碼到的DbContext OnModelCreating方法將MyEntityId.Value映射到所需的列名:現在
modelBuilder
.Entity<MyEntity>()
.Property(x => x.MyEntityId.Value)
.HasColumnName("id");
,上述所有的編譯罰款。但只要與表交互,我會得到以下例外:
An exception of type 'System.Data.Entity.ModelConfiguration.ModelValidationException'
occurred in EntityFramework.dll but was not handled in user code
EntityType 'MyEntity' has no key defined. Define the key for this MyEntity.
顯然,該實體確實有一個已定義的密鑰。
與一種類型的屬性作爲密鑰 - 嘗試#2
所以,我試圖消除從模型[鍵]屬性,並修改了流利API代碼,如下所示:
modelBuilder
.Entity<MyEntity>()
.HasKey(x => x.MyEntityId.Value);
.Property(x => x.MyEntityId.Value)
.HasColumnName("id")
但是這個代碼將生成以下異常:
An exception of type 'System.InvalidOperationException' occurred in
EntityFramework.dll but was not handled in user code
Additional information: The properties expression 'x => x.MyEntityId.Value'
is not valid. The expression should represent a property:
C#: 't => t.MyProperty' VB.Net: 'Function(t) t.MyProperty'.
When specifying multiple properties use an anonymous type:
C#: 't => new { t.MyProperty1, t.MyProperty2 }'
VB.Net: 'Function(t) New With { t.MyProperty1, t.MyProperty2 }'.
與一類性質的關鍵 - 在誘惑#3
因此,在挖掘SO後,它看起來像EF需要一個屬性,而不僅僅是一個公共領域。所以我修改了語義類型引入一個新的「EFValue」屬性,如下所示:
public class MyEntityId: SemanticType<Guid>
{
public MyEntityId()
: base(IsValid, Guid.Empty)
{ }
public MyEntityId(Guid value)
: base(IsValid, value)
{ }
public static bool IsValid(Guid value)
{
return true;
}
public Guid EFValue
{
get { return Value; }
}
}
...並修改了流利的API代碼,如下所示:
modelBuilder
.Entity<MyEntity>()
.HasKey(x => x.MyEntityId.EFValue);
.Property(x => x.MyEntityId.Value)
.HasColumnName("id")
但後來我得到的同樣的'System.InvalidOperationException'異常。
是不是可以像這樣定義類型的屬性作爲EF6中的主鍵?
把自己當成關係數據庫管理系統,你如何處理類型作爲關鍵字?如果你可以期待EF做到這一點。 – dotctor
即使你可以這樣做,你確定你想要嗎?想想看,如果EF必須序列化(很可能是二進制)表格的鍵,這將導致非常大且難以索引的鍵。鍵應該是簡單和可排序的,我不確定你通過將PK或FK改爲語義類型來獲得任何東西。 –
我很努力地想知道爲什麼這是一個問題,tbh。我不是試圖使用類型作爲鍵 - 只是類型實例屬性的值 - 在這種情況下,數據庫表中的鍵仍然是GUID。類型本身有一個我想用作鍵的屬性。在我可能的無知中,我沒有看到使用Fluent API將屬性映射到列的區別:modelBuilder 。實體().Property(x => x.MyEntityId.Value)。 HasColumnName( 「ID」)。我顯然缺少一些東西。 –
user2209634