我是实体框架的新手,当我的模型看起来像这样(大大简化)时,很难弄清楚如何使用联接进行查询
class Customer
{
public int Id {get; set;}
public Vehicles Vehicles {get; set;}
}
class Vehicles
{
public List<Vehicle> Items {get; set;}
}
class Vehicle
{
public int Id {get; set;}
public int CustomerId {get; set;}
}
如果我将List<Vehicle>
直接放在客户类别上。我可以像这样
builder.Entity<Customer>()
.HasMany(x => x.Items)
.WithOne()
.HasForeignKey(x => x.CustomerId);
那我可以做到这一点,然后用车辆取回客户对象
db.Customers.Include(x => x.Items).FirstOrDefault(x => x.Id == 1);
我不了解的是如何使用原始模型集执行此操作。如果可能的话,我想保持他们的状态。我试过在我的onModelCreating
方法中进行各种版本的操作,但是没有运气。
builder.Entity<Customer>(t =>
{
t.OwnsOne(x => x.Vehicles, v =>
{
v.HasMany(x => x.Items).WithOne().HasForeignKey(x => x.CustomerId);
});
});
答案 0 :(得分:2)
可以映射原始类,但以与直觉相反的方式。
由于Vehicles
类只是一个容器,因此按照您的尝试将其映射为拥有实体似乎是最自然的方法。但是,当前EF Core不允许拥有实体在关系的主要方面,因此您需要这样做。
因此,您需要将Vehicles
类映射为与Customer
共享同一表的常规“实体”,即所谓的table splitting。您必须明确地执行EF Core对所拥有实体所做的所有工作-定义一个shadow property,并且映射是与Customer
一对一关系的PK和FK。您还需要显式地将Vehicle.CustomerId
映射为FK,因为从EF的角度来看,Vehicle
与Vehicles
而不是Custome
相关,因此,传统的FK假定的属性/列名称将为VehiclesId
。请注意,使用此模型,您将永远无法定义Customer
的反向导航属性Vehicle
。
话虽如此,这是所需的流畅配置:
modelBuilder.Entity<Vehicles>(builder =>
{
// Table
builder.ToTable(modelBuilder.Entity<Customer>().Metadata.Relational().TableName);
// PK
builder.Property<int>("Id");
builder.HasKey("Id");
// One-to-one relationship with Customer
builder.HasOne<Customer>()
.WithOne(e => e.Vehicles)
.HasForeignKey<Vehicles>("Id");
// One-to-many relationship with Vehicle
builder.HasMany(e => e.Items)
.WithOne()
.HasForeignKey(e => e.CustomerId);
});
和用法:
db.Customers
.Include(x => x.Vehicles.Items) // <--
// ...
答案 1 :(得分:0)