EF Core 中具有 TPH 继承的多对多
Many-to-many with TPH inheritance in EF Core
如果连接 table 的一侧是 table 中的派生 class,我在使用 EF 核心设置多对多连接 table 时遇到问题=]-每个层次结构设置。
设置如下:
class Chore
{
Guid Id;
}
class LaundryChore : Chore
{
// PROBLEMATIC
List<Clothing> ManyClothing;
}
class FoldingChore : Chore
{
Clothing SingleClothing;
}
class Clothing
{
Guid Id;
// PROBLEMATIC
List<Chore> Chores;
}
我已经为 TPH 设置了鉴别器并且一切正常。如果 ManyClothing
字段在 Chore
class 上,那么我可以这样做:
builder.Entity<Clothing>().HasMany(clothing => clothing.Chores)
.WithMany(chore => chore.ManyClothing);
这按预期工作。
但是由于 ManyClothing
字段在 LaundryChore
class 上,我会收到上面的 DNE 错误。
我试过换方向:
builder.Entity<LaundryChore>().HasMany(chore => clothing.ManyClothing)
.WithMany(clothing => clothing.Chores);
我得到一个转换错误:
Cannot implicitly convert type 'System.Collections.Generic.List' to 'System.Collections.Generic.IEnumerable'
如果我改为:
class Clothing
{
Guid Id;
List<LaundryChore> Chores;
}
然后我得到的错误是:
The filter expression ... cannot be specified for entity type 'LaundryChore'. A filter may only be applied to the root entity type 'Chore'
任何指导将不胜感激 - 谢谢!
A navigation properties can only participate in a single relationship.
不是限制类型,而是关系限制。例如,如果您只有 Chore
和 Clothing
类 :
public class Chore
{
public int Id { get; set; }
public List<Clothing> ManyClothingToLaundry { get; set; }
public Clothing SingleClothingToFolding { get; set; }
}
public class Clothing
{
public int Id { get; set; }
public List<Chore> Chores { get; set; }
}
现在,您想为服装添加杂务:
clothing.Chores.Add(chore);
这会给洗衣或叠衣服增加麻烦吗? EF Core 在这种情况下无法知道。
在您的特定情况下,EF Core 可以从类型中检测到关系,但未实现此功能。
如果 Clothing 有两个不同的关系,那么 Clothing 需要两个导航属性:
public class Clothing
{
public int Id { get; set; }
public List<Chore> FoldingChores { get; set; }
public List<Chore> LaundryChores { get; set; }
public IEnumerable<Chore> Chores => FoldingChores.Union(LaundryChores);
}
...
protected override void OnModelCreating(ModelBuilder builder)
{
...
builder.Entity<Clothing>().Ignore(c => c.Chores);
builder.Entity<Clothing>()
.HasMany<LaundryChore>(nameof(Clothing.LaundryChores))
.WithMany(chore => chore.ManyClothing);
builder.Entity<Clothing>()
.HasMany<FoldingChore>(nameof(Clothing.FoldingChores))
.WithOne(chore => chore.SingleClothing);
}
Clothing.FoldingChores
是例子中基础实体Chore
的集合,但也可以直接是结局类型FoldingChore
的集合。与 Clothing.LaundryChores
相同:
public class Clothing
{
public int Id { get; set; }
public List<FoldingChore> FoldingChores { get; set; }
public List<LaundryChore> LaundryChores { get; set; }
public IEnumerable<Chore> Chores => FoldingChores.Cast<Chore>().Union(LaundryChores.Cast<Chore>());
}
如果连接 table 的一侧是 table 中的派生 class,我在使用 EF 核心设置多对多连接 table 时遇到问题=]-每个层次结构设置。
设置如下:
class Chore
{
Guid Id;
}
class LaundryChore : Chore
{
// PROBLEMATIC
List<Clothing> ManyClothing;
}
class FoldingChore : Chore
{
Clothing SingleClothing;
}
class Clothing
{
Guid Id;
// PROBLEMATIC
List<Chore> Chores;
}
我已经为 TPH 设置了鉴别器并且一切正常。如果 ManyClothing
字段在 Chore
class 上,那么我可以这样做:
builder.Entity<Clothing>().HasMany(clothing => clothing.Chores)
.WithMany(chore => chore.ManyClothing);
这按预期工作。
但是由于 ManyClothing
字段在 LaundryChore
class 上,我会收到上面的 DNE 错误。
我试过换方向:
builder.Entity<LaundryChore>().HasMany(chore => clothing.ManyClothing)
.WithMany(clothing => clothing.Chores);
我得到一个转换错误:
Cannot implicitly convert type 'System.Collections.Generic.List' to 'System.Collections.Generic.IEnumerable'
如果我改为:
class Clothing
{
Guid Id;
List<LaundryChore> Chores;
}
然后我得到的错误是:
The filter expression ... cannot be specified for entity type 'LaundryChore'. A filter may only be applied to the root entity type 'Chore'
任何指导将不胜感激 - 谢谢!
A navigation properties can only participate in a single relationship.
不是限制类型,而是关系限制。例如,如果您只有 Chore
和 Clothing
类 :
public class Chore
{
public int Id { get; set; }
public List<Clothing> ManyClothingToLaundry { get; set; }
public Clothing SingleClothingToFolding { get; set; }
}
public class Clothing
{
public int Id { get; set; }
public List<Chore> Chores { get; set; }
}
现在,您想为服装添加杂务:
clothing.Chores.Add(chore);
这会给洗衣或叠衣服增加麻烦吗? EF Core 在这种情况下无法知道。
在您的特定情况下,EF Core 可以从类型中检测到关系,但未实现此功能。
如果 Clothing 有两个不同的关系,那么 Clothing 需要两个导航属性:
public class Clothing
{
public int Id { get; set; }
public List<Chore> FoldingChores { get; set; }
public List<Chore> LaundryChores { get; set; }
public IEnumerable<Chore> Chores => FoldingChores.Union(LaundryChores);
}
...
protected override void OnModelCreating(ModelBuilder builder)
{
...
builder.Entity<Clothing>().Ignore(c => c.Chores);
builder.Entity<Clothing>()
.HasMany<LaundryChore>(nameof(Clothing.LaundryChores))
.WithMany(chore => chore.ManyClothing);
builder.Entity<Clothing>()
.HasMany<FoldingChore>(nameof(Clothing.FoldingChores))
.WithOne(chore => chore.SingleClothing);
}
Clothing.FoldingChores
是例子中基础实体Chore
的集合,但也可以直接是结局类型FoldingChore
的集合。与 Clothing.LaundryChores
相同:
public class Clothing
{
public int Id { get; set; }
public List<FoldingChore> FoldingChores { get; set; }
public List<LaundryChore> LaundryChores { get; set; }
public IEnumerable<Chore> Chores => FoldingChores.Cast<Chore>().Union(LaundryChores.Cast<Chore>());
}