EF6 - 在派生类中使用基类属性TPH外键映射 [英] EF6 - TPH foreign key mapping in derived classes using base class property

查看:729
本文介绍了EF6 - 在派生类中使用基类属性TPH外键映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用实体框架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:


  • 编号:整型,主键

  • TagType :字符串,确定类型的标签,无论是usertag或movietag的

  • ITEMID :INT,包含该项目的ID这被称为(一个用户ID或电影ID)

  • Id: int, primary key
  • TagType: 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);
        }
    }
}



时引发的例外是

The exception that is thrown is:

未处理的异常:System.InvalidOperationException:国外关键部件ITEMID不在类型UserTag声明的属性。验证它尚未明确从模型中排除,它是一个有效的基本属性

是在 ITEMID 属性未声明的类型 UserTag ,但它是从基继承标签类。对我来说,似乎这个映射应该是可能的。这是一个bug或实体的限制框架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.

在不同的方式想想吧。如果它的工作方式你如何试图定义它也就没有理由让用户电影导航在子实体性能 - 这将是足有父单一导航属性。你必须定义它们在儿童实体,因为它们是不同的为他们每个人也意味着你需要有两个不同的外键的事实。

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.

您需要拥有独立的用户ID MovieId 在其特定的标签。

You need to have separate UserId and MovieId in their specific tags.

这篇关于EF6 - 在派生类中使用基类属性TPH外键映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆