gpt4 book ai didi

c# - EF6 - 使用基类属性的派生类中的 TPH 外键映射

转载 作者:太空狗 更新时间:2023-10-30 01:04:58 26 4
gpt4 key购买 nike

我将 Entity Framework 6.0.2 与现有数据库一起使用,其中标签存储在单个表中,如下所示:

  • Id: int, 主键
  • TagType:字符串,判断标签的类型,“usertag”或“movietag”
  • ItemId:int,包含所引用项目的 ID(用户 ID 或电影 ID)

下面的类描述了这种情况:

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 属性的值支持。我的映射如下:

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);
}
}

现在,当我尝试使用以下代码使用此映射时,出现异常:

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 中的错误还是限制?

最佳答案

这是一个限制。 EF 与关系数据库的工作方式紧密相关。你在数据库方面试图做的是在单个 ItemId 列上放置两个外键约束。数据库中的外部约束不是有条件的,因此无论标记类型如何,记录都将始终使用两个约束。这不是您想要的,因为这样的定义将始终要求每个标签都存在具有特定 Id 的用户和电影。

换一种方式思考。如果它按照您尝试定义它的方式工作,那么就没有理由在子实体中具有 UserMovie 导航属性 - 具有单个就足够了父级中的导航属性。事实上,您必须在子实体中定义它们,因为它们对于每个实体都是不同的,这也意味着您需要有两个不同的外键。

您需要在其特定标签中包含单独的 UserIdMovieId

关于c# - EF6 - 使用基类属性的派生类中的 TPH 外键映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20744278/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com