我参与了一个使用实体框架代码优先将现有C#代码映射到数据库的项目。我不打算在这里重现代码本身,但我会提出一些应该涵盖相同问题的伪代码。使用实体框架代码首先获取InvalidOperationException
我想映射一个类到其他类的列表的数据库。我将向您展示一个示例:
public Class ListClass
{
public List<SubClassA> ListOne
{
get { return BaseClass.OfType<SubClassA>().Where(b => !b.BoolOne && b.BoolTwo).ToList(); }
}
public List<SubClassA> ListTwo
{
get { return BaseClass.OfType<SubClassA>().Where(b => b.BoolOne && b.BoolTwo).ToList(); }
}
}
public abstract class BaseClass
{
public bool BoolOne {get; set;}
#Region EF
public GUID PrimaryKey {get; set;}
public GUID ListClassForeignKey {get; set;}
#EndRegion
}
public class SubClassA : BaseClass
{
public bool BoolTwo {get; set}
}
Class SubClassB : BaseClass
{
//Contents..
}
摘要:ListClass包含SubClassA的列表。 BaseClass和SubClassA不知道有关ListClass的任何内容。 BaseClass中的GUID属性被添加用于实体框架,否则不存在已经改变的类。这就是为什么我们在这个项目中使用Fluent API的原因:
class ListClassConfiguration : EntityTypeConfiguration<ListClass>
{
public ListClassConfiguration()
{
HasKey(f => f.PrimaryKey);
Property(f => f.PrimaryKey).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
HasMany(f => f.ListOne).WithOptional().HasForeignKey(f => f.ListClassForeignKey);
HasMany(f => f.ListTwo).WithOptional().HasForeignKey(f => f.ListClassForeignKey);
}
}
在Context-class中,我们只需添加此配置。 只要模型更改,数据库就会被删除。 我目前使用TPH映射为BaseClass和它的子类。
当我尝试添加并保存在列表中refered对象ListClass,我得到这个异常:
InvalidOperationException异常。 外键组件'ListClassForeignKey'不是'SubClassA'类型的声明属性。验证它没有被明确地从模型中排除,并且它是一个有效的基本属性。
那么,有什么建议吗?
编辑:我注意到,在真实的项目中,似乎有空的列表。我试图删除配置类中的foreignkey,并且我得到了一个没有内容的数据表(一列只有NULL值)。在这个例子中,这意味着只有名字'BaseClass'的TPH表是空的/只有NULL值。这能解释一些问题吗?