实体框架嵌套连接

问题描述 投票:1回答:2

我是实体框架的新手,当我的模型看起来像这样时,我很难弄清楚如何用连接查询(大大简化)

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);
    });
});
entity-framework .net-core
2个回答
2
投票

可以映射原始类,但是以非常违反直觉的方式。

由于Vehicles类只是一个容器,因此将其作为所拥有的实体进行映射似乎是最自然的方式。但是,目前EF Core不允许拥有实体处于关系的主要方面,在您的情况下,这是必需的。

因此,您需要将Vehicles类映射为与Customer共享相同表的常规“实体” - 即所谓的table splitting。你必须明确表示EF Core对所拥有的实体隐式执行的所有操作 - 定义shadow property和map是与Customer一对一关系的PK和FK。您还需要明确地将Vehicle.CustomerId映射为FK,因为从EF的角度来看,VehicleVehicles而不是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) // <--
    // ...

0
投票

使用.Join

请参阅此问题以获取一些示例:

Entity Framework Join 3 Tables

© www.soinside.com 2019 - 2024. All rights reserved.