【问题标题】:Entity Framework 6 TPT and foreign keysEntity Framework 6 TPT 和外键
【发布时间】:2018-11-13 16:00:59
【问题描述】:

我一直试图让 EF 在 TPT 场景中使用外键。我认为一个表是一对多的关系,而另一个表是一对一的关系,这很复杂。

这段代码被归结为说明问题(GitHub:https://github.com/Dash/EFTest for VS project)。

当我在基本 Persons 表中创建外键时,我收到关于类型不匹配的错误:

产品:FromRole:NavigationProperty 'Product' 无效。类型 AssociationType 中 FromRole 'Product_Buyers_Target' 的 'Buyer' “Product_Buyers”必须与“Person”类型完全匹配 此 NavigationProperty 已声明。

为了尝试解决这个问题,我将 Product 导航属性向上移动到子级,但由于数据库中不存在 ProductId 列,我得到一个错误 - 它试图查看派生表而不是基表。

我不完全清楚如何解决这个问题,一直在转圈和谷歌搜索,直到我的眼睛流血。有人可以帮忙吗?

型号

public abstract class Person
{
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual Product Product { get; set; }
}

public class Buyer : Person
{
    public string ShipTo { get; set; }
}

public class Seller : Person
{
    public int Rating { get; set; } = 0;
}

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

    public string Description { get; set; }
    public virtual Seller Seller { get; set; }
    public virtual IList<Buyer> Buyers { get; set; }
}

架构

public class ProductSchema : EntityTypeConfiguration<Product>
{
    public ProductSchema()
    {
        HasKey(p => p.Id)
            .Property(p => p.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        Property(p => p.Description)
            .HasMaxLength(256);

        HasOptional(p => p.Seller)
            .WithRequired(i => i.Product)
            .Map(m => m.MapKey("ProductId"));

        HasMany(p => p.Buyers)
            .WithRequired(i => i.Product)
            .Map(m => m.MapKey("ProductId"));
    }
}

public class PersonSchema : EntityTypeConfiguration<Person>
{
    public PersonSchema()
    {
        ToTable("Persons");

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

        Property(p => p.Name)
            .HasMaxLength(128);
    }
}

public class SellerSchema : EntityTypeConfiguration<Seller>
{
    public SellerSchema()
    {
        ToTable("Sellers");

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

        Property(s => s.Rating);
    }
}

public class BuyerSchema : EntityTypeConfiguration<Buyer>
{
    public BuyerSchema()
    {
        ToTable("Buyers");

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

        Property(b => b.ShipTo)
            .HasMaxLength(256);
    }
}

SQL

CREATE TABLE Products (
Id INT IDENTITY PRIMARY KEY,
[Description] nvarchar(256),
)

create table Persons (
    Id int IDENTITY PRIMARY KEY,
    [Name] nvarchar(128),
    ProductId INT NOT NULL,
    FOREIGN KEY (ProductId) REFERENCES Products(Id)
)

CREATE TABLE Buyers (
    Id INT PRIMARY KEY,
    ShipTo nvarchar(256)
)

CREATE TABLE Sellers (
    Id INT PRIMARY KEY,
    Rating INT NOT NULL DEFAULT 0
)

DECLARE @ProductId int;
INSERT INTO Products ([Description]) VALUES ('Widget');
SET @ProductId = @@IDENTITY;

INSERT INTO Persons ([Name], ProductId) VALUES ('Bob the seller', @ProductId);
INSERT INTO Sellers (Id, Rating) VALUES (@@IDENTITY, 0);

INSERT INTO Persons ([Name], ProductId) VALUES ('Bert the buyer', @ProductId);
INSERT INTO Buyers (Id, ShipTo) VALUES (@@IDENTITY, 'Somewhere');

【问题讨论】:

  • 将以下属性添加到Person 类 -> public int ProductId { get; set; }
  • 这不起作用。为了将命名属性用作外键,您需要使用 .WithMany().HasForeignKey(),它不适用于一对一关系(卖方)。从功能上讲,这与使用我目前在 MapKey() 中使用的隐藏外键没有什么不同。

标签: c# inheritance entity-framework-6


【解决方案1】:

我一直无法找到让 EF 处理这个概念的方法。

最后,我不得不从 Persons 中删除 ProductId 外键,并在 EF 开始之前在买家和卖家中都有重复的副​​本。这违背了规范化,但有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-15
    • 1970-01-01
    • 2023-01-13
    • 1970-01-01
    • 2017-08-05
    • 1970-01-01
    • 2016-08-08
    • 1970-01-01
    相关资源
    最近更新 更多