澄清:我没有尝试将类/类型存储在数据库字段中,或者使用类/类型本身作为键值。我试图使用Class / Type的单个属性(在本例中为Guid)作为键。
虽然我认为它与此特定问题严格相关,但它可能对上下文有用:我正在尝试在我的最新项目中实施Semantic Types。我在整个代码中取得了一些成功,事实上已经确定了一些可能不会很快被识别出来的错误。
在一些Fluent API代码的帮助下,一切都很好地将我的语义类型与EF6集成在非键字段中。
但是,当尝试对键字段使用语义类型时,EF会生成一个运行时异常,说明没有定义键 - 显然有。
使用简单的Guid作为键
以下是我使用的不使用语义类型的EF实体的示例:
public partial class MyEntity
{
[Key]
public Guid id { get; set; }
public string SomeData { get; set; }
}
以上工作正常。
将Type属性作为键 - 尝试#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.
显然,实体确实有一个键定义。
将Type属性作为键 - 尝试#2
所以,我尝试从模型中删除[key]属性,并修改了Fluent 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 }'.
将Type属性作为键 - 尝试#3
因此,在挖掘SO之后,看起来EF需要一个属性,而不仅仅是一个公共领域。所以我修改了语义类型来引入一个新的&#34; EFValue&#34;财产,如下:
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; }
}
}
...并修改了Fluent API代码,如下所示:
modelBuilder
.Entity<MyEntity>()
.HasKey(x => x.MyEntityId.EFValue);
.Property(x => x.MyEntityId.Value)
.HasColumnName("id")
然后我得到了相同的&#39; System.InvalidOperationException&#39;异常。
是否无法在EF6中将此类型的属性定义为主键?
答案 0 :(得分:1)
错误很明显,你无法做你想做的事。只需在实体级别包装ID属性,它就可以工作:
public partial class MyEntity
{
public MyEntityId BadIdea { get; set; }
[Key]
public Guid Id
{
get
{
// needs null check
return BadIdea.Value;
}
set
{
// needs null check
BadIdea.Value = value;
}
}
}