澄清:我不打算将类/类型存储在数据库字段中,也不打算使用类/类型本身作为键值。我试图使用类/类型的单个属性(在本例中为Guid)作为键。
虽然我认为它与这个特定的问题没有严格的关联,但它可能对上下文很有用:我正在尝试在我的最新项目中实现语义类型。在我的代码中,我已经取得了一些成功,事实上,我发现了一些错误,它们可能不会很快被识别出来。
在一些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
因此,我尝试从模型中删除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 }'.具有类型属性的作为密钥尝试#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; }
}
}..。并修改了Fluent API代码,如下所示:
modelBuilder
.Entity<MyEntity>()
.HasKey(x => x.MyEntityId.EFValue);
.Property(x => x.MyEntityId.Value)
.HasColumnName("id")但是,我得到了同样的“System.InvalidOperationException”例外。
不能将这样的类型的属性定义为EF6?中的主键
发布于 2015-11-02 17:09:54
这个错误非常清楚地表明,你不能做你想做的事。只需在实体级别包装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;
}
}
}https://stackoverflow.com/questions/33442875
复制相似问题