让我们说我想拥有一个A
且很多B
的班级A
;
我可以通过创建类AB
,向ICollection<AB> ABs
和A
类添加B
字段,然后通过B
访问ABs
来实现这一点。类A
的属性。这可行。
但是我想知道是否有一种方法可以直接从类B
访问相关的A
数据,而不是通过ABs
属性来访问数据。
我可以想象有几种方法可以做到(我都没有设法上班):
public ICollection<B> Bs => this.ABs.Select(item => item.B).ToList();
,但是没有,我没有空异常,即使我在此ABs
中确实包含了Bs
和context.As.Include(item => item.ABs).ThenInclude(item => item.B);
。
ef core的流畅api(不知道怎么做)
using Microsoft.EntityFrameworkCore;
using System;
using Context;
namespace ConsoleApp1 {
class Program
{
static void Main(string[] args)
{
using var context = new ZContext();
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
var A = context.As.Include(item => item.ABs).ThenInclude(item => item.B);
foreach (var a in A) {
Console.WriteLine(a.Bs);
}
return;
}
}
}
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Context
{
public class IDed
{
#region Constructors
public IDed()
{
ID = Guid.NewGuid();
}
#endregion
public Guid ID { get; set; }
}
public class A : IDed
{
public ICollection<AB> ABs { get; set; }
public ICollection<B> Bs {
get {
return ABs.Select(item => item.B).ToList();
}
}
}
public class B : IDed
{
public ICollection<AB> ABs { get; set; }
}
public class AB
{
#region Constructors
public AB()
{
}
public AB(A a, B b)
{
this.AID = a.ID;
this.BID = b.ID;
}
#endregion
public A A { get; set; } public Guid AID { get; set; }
public B B { get; set; } public Guid BID { get; set; }
}
public class ZContext : DbContext
{
public DbSet<A> As { get; set; }
public DbSet<B> Bs { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Data Source=111.db3");
}
protected override void OnModelCreating(ModelBuilder mb)
{
#region Keys
mb.Entity<AB>().HasKey(item => new { item.AID, item.BID });
#endregion
#region Relations
// ???
#endregion
var a1 = new A();
var a2 = new A();
mb.Entity<A>().HasData(a1, a2);
var b1 = new B();
var b2 = new B();
mb.Entity<B>().HasData(b1, b2);
mb.Entity<AB>().HasData(
new AB(a1, b1),
new AB(a1, b2),
new AB(a2, b1),
new AB(a2, b2)
);
}
}
}
使用第一种方法,即使我System.ArgumentNullException: 'Value cannot be null. (Parameter 'source')'
和Include
的字段都相同,也会出现ThenInclude
错误。
我意识到AB
类必须以任何方式保留,但是可以实现此配置,以及这样做的正确方法。
答案 0 :(得分:1)
该异常是由EF推断默认映射约定引起的。也就是说,在构建实体模型时,EF遇到属性A.Bs
并尝试为其找到数据库映射。正是在很早的时候发生异常。知道这一点后,修复很容易:只需取消映射属性即可:
[NotMapped]
public ICollection<B> Bs
{
get
{
return ABs.Select(item => item.B).ToList();
}
}
或
protected override void OnModelCreating(ModelBuilder mb)
{
...
mb.Entity<A>().Ignore(a => a.Bs);
当然,即使没有例外,也应取消映射该属性,因为您不希望该属性反映在数据库关联中。