EF6 - TPH foreign key mapping in derived classes using base class property(EF6 - 使用基类属性的派生类中的 TPH 外键映射)
问题描述
我将 Entity Framework 6.0.2 与现有数据库一起使用,其中标签存储在单个表中,如下所示:
I am using Entity Framework 6.0.2 with an existing database in which tags are stored in a single table that looks like this:
Id
:int,主键TagType
:字符串,确定标签的类型,usertag"或movietag"ItemId
:int,包含被引用项目的ID(用户ID或电影ID)
Id
: int, primary keyTagType
: string, determine the type of tag, either "usertag" or "movietag"ItemId
: int, contains the Id of the item to which is referred (either a User Id or a Movie Id)
以下类描述了这种情况:
The following classes describe this situation:
public class User
{
public int Id { get; set; }
}
public class Movie
{
public int Id { get; set; }
}
public abstract class Tag
{
public int Id { get; set; }
public int ItemId { get; set; }
}
public class UserTag : Tag
{
public virtual User User { get; set; }
}
public class MovieTag : Tag
{
public virtual Movie Movie { get; set; }
}
如您所见,我的派生类具有导航属性,这些属性由基类中的 ItemId
属性的值支持.我的映射如下:
As you can see my derived classes have navigation properties, which are backed by the value of the ItemId
property in the base class. My mapping is as follows:
public class Context : DbContext
{
public DbSet<Tag> Tags { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Tag>()
.Map<UserTag>(m => m.Requires("TagType").HasValue("usertag"))
.Map<MovieTag>(m => m.Requires("TagType").HasValue("movietag"));
modelBuilder.Entity<UserTag>()
.HasRequired(m => m.User).WithMany().HasForeignKey(m => m.ItemId);
modelBuilder.Entity<MovieTag>()
.HasRequired(m => m.Movie).WithMany().HasForeignKey(m => m.ItemId);
}
}
现在,当我尝试使用以下代码使用此映射时,出现异常:
Now when I try to use this mapping using the following code, I get an exception:
using System.Data.Entity;
class Program
{
static void Main()
{
using (var db = new Context())
{
db.Database.Delete();
db.Database.Initialize(false);
}
}
}
抛出的异常是:
未处理的异常:System.InvalidOperationException:外键组件ItemId"不是UserTag"类型的声明属性.验证它没有被明确地从模型中排除,并且它是一个有效的原始属性
是的,ItemId
属性没有在 UserTag
类型上声明,但它是从基础 Tag
类继承的.在我看来,这种映射应该是可能的.这是 Entity Framework 6 中的错误还是限制?
Yes the ItemId
property is not declared on the type UserTag
, but it is inherited from the base Tag
class. To me it seems that this mapping should be possible. Is this a bug or a restriction in Entity Framework 6?
推荐答案
这是一个限制.EF 与关系数据库的工作方式密切相关.您在数据库方面尝试做的是将两个外键约束放在单个 ItemId
列上.数据库中的外部约束不是有条件的,因此无论标签类型如何,记录都将始终使用这两个约束.这不是你想要的,因为这样的定义总是要求每个标签都存在具有特定 ID 的用户和电影.
It is a restriction. EF is quite tightly bound to the way how relational database works. What you are trying to do in terms of the database is to put two foreign key constraints on single ItemId
column. The foreign constraint in database is not conditional so the record will always use both constraints no matter of the tag type. That is not what you want because such definition will always require both user and movie with specific Id to exist for every single tag.
以不同的方式思考它.如果它按照您尝试定义它的方式工作,则没有理由在子实体中拥有 User
和 Movie
导航属性 - 拥有单个导航属性就足够了父级中的导航属性.您必须在子实体中定义它们,因为它们每个都不同,这也意味着您需要有两个不同的外键.
Think about it in different way. If it works the way how you are trying to define it there would be no reason why to have User
and Movie
navigation properties in child entities - it would be enough to have single navigation property in parent. The fact that you have to define them in child entities because they are different for each of them also means you need to have two different foreign keys.
您需要在它们的特定标签中具有单独的 UserId
和 MovieId
.
You need to have separate UserId
and MovieId
in their specific tags.
这篇关于EF6 - 使用基类属性的派生类中的 TPH 外键映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:EF6 - 使用基类属性的派生类中的 TPH 外键映射
基础教程推荐
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01
- 如何激活MC67中的红灯 2022-01-01
- SSE 浮点算术是否可重现? 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01
- MS Visual Studio .NET 的替代品 2022-01-01
- c# Math.Sqrt 实现 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01
- rabbitmq 的 REST API 2022-01-01