DeviceModel 和 ComponentModel 之间存在多对多关系。
public class DeviceModel
{
public int ID { get; set; }
public string TagNumber { get; set; } = "";
public List<ComponentModel> Components { get; set; } = [];
}
public class ComponentModel
{
public int ID { get; set; }
string vendor = "";
public string Vendor { get => vendor.TrimEnd(); set => vendor = value; }
string model = "";
public string Model { get => model.TrimEnd(); set => model = value; }
public List<DeviceModel> Devices { get; set; } = [];
}
[PrimaryKey(nameof(ComponentID), nameof(DeviceID))]
public class DeviceComponentModel
{
[ForeignKey("Components")]
public int ComponentID { get; set; }
[ForeignKey("Devices")]
public int DeviceID { get; set; }
}
OnModelCreating 有
modelBuilder.Entity<ComponentModel>()
.HasMany(e => e.Devices)
.WithMany(e => e.Components)
.UsingEntity<DeviceComponentModel>();
所有表均已填充。
但是当它选择设备时,组件列表不会被填充。
device = deviceSummaryContext.Devices
.Where(x => x.ID == deviceID)
.AsEnumerable()
.FirstOrDefault(new DeviceModel());
我们正在尝试遵循此处阐明的约定,但我们显然遗漏了一些东西,因为使用 Effort 作为内存数据库的单元测试或使用 SQL 的实时测试都没有填充列表。
tl;博士; Svyatoslav Danyliv 为我指明了正确的方向,但仍然无法让它正常工作。最终改为手动完成。
我尝试了 Lazy(使用代理)、Eager 和 Explicit 加载,但没有成功。
Eager 使用 Include 并且看起来像这样:
device = deviceSummaryContext.Devices
.Where(x => x.ID == deviceID)
.Include(x => x.Components)
.AsEnumerable()
.FirstOrDefault(new DeviceModel());
Lazy 可以使用代理,将其注入到构造函数中,如下所示:
private DeviceModel(ILazyLoader lazyLoader)
{
LazyLoader = lazyLoader;
}
但首先它抱怨没有不带参数的构造函数。在我添加一个之后,毫不奇怪,它只命中那个构造函数,而不是这个构造函数。
我们尝试了显式加载,如:
context.Entry(device)
.Collection(x => x.Components)
.Load();
这些都不起作用。 我们最终得到的是:
List<ComponentModel> components = context.Components
.Join(context.DeviceComponents,
c => c.ID,
dc => dc.ComponentID,
(c, dc) => new { c, dc })
.Where(x => x.dc.DeviceID == device.ID)
.Select(x => x.c).ToList();
foreach(var item in components) {
model.Components.Add(item);
}
return model;
效果非常好。 ́_(ツ)_/́