c# - 返回带有列表对象的列表对象

标签 c# entity-framework linq entity-framework-6

我有三个表 Car Makes、Car Model 和 CarsandModel。我有 Carsand 模型表,因为一个模型可以由多个制造商构建。我想返回包含车型列表的汽车品牌列表。我现在拥有的 longic 没有过滤汽车型号的列表。

我已经尝试添加一个 where 语句,但我仍然没有得到正确的返回值

public class CarMake
{
    public int CarMakeId { get; set; }
    public string CarMakeName { get; set; }
    public List<CarModel> CarModel { get; set; }

}
public class CarModel
{
    public int CarModelId { get; set; }
    public string CarModelName { get; set; }
}
public class CarsandModel
{
    public int CarMakeId { get; set; }
    public int CarModelId { get; set; }
}


var CarModel = (from cmake in db.CarModel
               select new CarModel
               {
                   CarModelId = cmake.CarMakeId,
                   CarModelName = cmake.CarMakeName,
                   CarMake= (from cmake in db.Carmake
                               join cam in db.CarsandModel on cmake.CarMakeId equals cam.CarMakeId
                               where (camodel.CarMakeId == cmake.CarMakeId)
                               select new Asset
                               {
                                   CarMakeId = cmodel.CarMakeId,
                                   CarMakeName = cmodel.CarMakeName
                               }).ToList()
               }
            ).ToList();

最佳答案

当使用 Entity Framework 时,人们倾向于自己(分组)连接表,而使用 ICollections 会容易得多。相反。

首先:stick to the Entity Framework Code-First Conventions!

例如:
每个CarMake有零个或多个 CarModels .您决定将其声明为 List<CarModel> .你确定CarModel[4]有明确的含义吗?我想知道什么 CarModel.Insert(4, new CarModel())将意味着在您的代码中。最好坚持使用您的数据库真正可以处理的接口(interface):ICollection<CarModel> .

CarMakes之间的关系和 CarModels似乎是多对多:每个CarMake有零个或多个 CarModels , 每个 CarModel由零个或多个 CarMakes 制作.

在关系数据库中,多对多关系是使用联结表实现的。你的类CarsAndModel表示此联结表中的一行。但是,在使用 Entity Framework 时,您无需提及联结表。当您正确设计您的类时, Entity Framework 会识别您的表之间的关系并为其创建适当的联结表。

class CarMake
{
    public int CarMakeId { get; set; }
    public string CarMakeName { get; set; }

    // every CarMake makes zero or more CarModels (many-to-many)
    public virtual ICollection<CarModel> CarModels { get; set; }
}
class CarModel
{
    public int CarModelId { get; set; }
    public string CarModelName { get; set; }

    // every CarModel is made by zero or more CarMakes (many-to-many)
    public virtual ICollection<CarMake> CarMakes {get; set;}
}

In entity framework the columns of the tables are represented by non-virtual properties. The virtual properties represent the relations between the tables (one-to-many, many-to-many, ...)

为了完整性,DbContext:

class CarContext : DbContext
{
    public DbSet<CarMake> CarMakes {get; set;}
    public DbSet<CarModel> CarModels {get; set;}
}

这就是 Entity Framework 检测多对多关系所需知道的全部内容。 Entity Framework 将为您创建联结表,并将根据需要使该表保持最新。

只有当您有充分的理由偏离代码优先约定(并且您可以说服您的项目负责人)时,您才需要属性或流畅的 API 来告知 Entity Framework 您的偏离。

但如果我无法访问联结表,我该如何加入这些表呢?

答案:不要进行(组)加入,使用 ICollections!

Requirement: Give me the CarModels, each with their CarMakes

var result = dbContext.CarModels
    .Where(carModel => ...)       // only if you don't want all CarModels
    .Select(carModel => new
    {
         // Select only the properties you actually plan to use!
         Id = carModel.CarModelId,
         Name = carModel.CarModelName,
         ...

         CarMakes = carModel.CarMakes
             .Where(carMake => ...)     // only if you don't want all CarMakes of this model
             .Select(carMake => new
             {
                  // again: select only the properties you plan to use
                  Id = carMake.CarMakeId,
                  Name = carMake.Name,
                  ...
             })
             .ToList(),
    }

Entity Framework 了解您的多对多关系并将为您创建适当的(组)连接。

关于c# - 返回带有列表对象的列表对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54422703/

相关文章:

c# - EF4调用存储过程

c# - 处理并计算数据库中保存的公式

LINQ to EF - 查找子集合的字符串属性至少部分匹配字符串列表中的所有记录的记录

c# - 自定义订单,可以吗?

c# - 如何读取 Windows 商店应用程序中的注册表值?

C# 单一项目组织

c# - .Select Vs .Include Vs .Select Many

c# - 带有参数 IQueryable<T> 和 Expression<Func<T, T>> 的 .net 泛型方法

c# - 如何重构 linq 查询以重用其部分

c# - .NET 查找 Windows sleep 设置