【发布时间】: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