关于困难EF代码第一次流利的API,TPH和外键 [英] Difficulty Concerning EF Code First Fluent API, TPH, and Foreign Keys

查看:136
本文介绍了关于困难EF代码第一次流利的API,TPH和外键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的数据库中的两个表。一个叫用户,另一种是名为小工具。在小工具表代表我的代码模型3个实体。其中一个实体,小部件,是其他两个实体父类, WidgetTypeA WidgetTypeB 。无论 WidgetTypeA WidgetTypeB 有导航属性到用户的实体,这是持久化到用户数据库中的表。我遇到了麻烦代码第一次使用相同的外键同时为 WidgetTypeA WidgetTypeB 实体(用户ID )。有谁知道如何做到这一点?它看起来像它应符合表每层次映射的一个常见问题。

I have two tables in my database. One is called Users, and the other is called Widgets. The Widgets table represents 3 entities in my code model. One of the entities, Widget, is a parent class for the other two entities, WidgetTypeA and WidgetTypeB. Both WidgetTypeA and WidgetTypeB have navigation properties to the User entity, which is persisted to the Users table in the database. I'm having trouble getting Code First to use the same foreign key for both the WidgetTypeA and WidgetTypeB entities (UserId). Does anyone know how to do this? It seems like it should be a common problem with Table Per Hierarchy mapping.

我的实体类如下:

public class Widget
{
    public int Id { get; set; }

    public string Name { get; set; }
}

class WidgetMap : EntityTypeConfiguration<Widget>
{
    public WidgetMap()
    {
        ToTable("Widgets");

        HasKey(w => w.Id);
        Property(w => w.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        Property(w => w.Name)
            .IsRequired()
            .HasMaxLength(75)
            .IsUnicode(true);
    }
}

public class WidgetTypeA : Widget
{
    public int UserId { get; set; }
    public virtual User User { get; set; }

    public string Color { get; set; }
    public int DepthLevel { get; set; }
}

class WidgetTypeAMap : EntityTypeConfiguration<WidgetTypeA>
{
    public WidgetTypeAMap()
    {
        Map(w => w.Requires("WidgetTypeId").HasValue(1));

        HasRequired(w => w.User)
            .WithMany(u => u.WidgetTypeAs)
            .HasForeignKey(w => w.UserId)
            .WillCascadeOnDelete(false);

        Property(w => w.Color)
            .IsOptional()
            .IsUnicode(true)
            .HasMaxLength(75);

        Property(w => w.DepthLevel)
            .IsOptional();
    }
}

public class WidgetTypeB : Widget
{
    public int UserId { get; set; }
    public virtual User User { get; set; }
}

class WidgetTypeBMap : EntityTypeConfiguration<WidgetTypeB>
{
    public WidgetTypeBMap()
    {
        Map(w => w.Requires("WidgetTypeId").HasValue(2));

        HasRequired(w => w.User)
            .WithMany(u => u.WidgetTypeBs)
            .HasForeignKey(w => w.UserId)
            .WillCascadeOnDelete(false);
    }
}

public class User
{
    public int Id { get; set; }
    public string Username { get; set; }
    public int Age { get; set; }

    public virtual ICollection<WidgetTypeA> WidgetTypeAs { get; set; }
    public virtual ICollection<WidgetTypeB> WidgetTypeBs { get; set; }
}

class UserMap : EntityTypeConfiguration<User>
{
    public UserMap()
    {
        ToTable("Users");

        HasKey(u => u.Id);

        Property(u => u.Username)
            .IsRequired()
            .HasMaxLength(75)
            .IsUnicode(true);

        Property(u => u.Age)
            .IsRequired();
    }
}



在任何情况下,我不断收到错误

At any rate, I keep getting the error

无效的列名称UserId1

Invalid column name 'UserId1'

当我尝试执行以下操作:

when I try to perform the following operations:

using (var entities = new MyEntities())
{
    User u = new User
    {
        Username = "Frank",
        Age = 14
    };
    entities.Users.Add(u);
    entities.SaveChanges();

    WidgetTypeA wa1 = new WidgetTypeA
    {
        Name = "0SDF81",
        UserId = u.Id,
        DepthLevel = 6
    };
    entities.WidgetTypeAs.Add(wa1);
    entities.SaveChanges();
}



不知道这是否可以固定或不。我总是可以指定窗口小部件表的第二个用户ID外键,但似乎没有意义的。或许有一种方法可以做到这一点使用流利的API?

Not sure if this can be fixed or not. I can always specify a second UserId foreign key for the Widgets table, but that seems pointless. Perhaps there's a way to do this using Fluent API?

推荐答案

您不能映射不同来源的实体定义为同一列的属性。这是EF限制。如果你的 WidgetTypeA 用户ID 财产和你的 WidgetTypeB 用户ID 属性他们必须在数据库中的不同列。如果您移动这两个用户ID 用户它应该工作从派生类型的父属性控件键入

You cannot map properties defined in different derived entities to the same column. That is limitation in EF. If your WidgetTypeA has UserId property and your WidgetTypeB has UserId property they must be different columns in the database. It should work if you move both UserId and User properties from derived types to the parent Widget type.

这篇关于关于困难EF代码第一次流利的API,TPH和外键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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