【问题标题】:Return list object with list object使用列表对象返回列表对象
【发布时间】:2019-01-29 13:57:06
【问题描述】:

我有三个表 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();

【问题讨论】:

  • 如果是 Linq-To-Entities,您应该使用导航属性而不是嵌套查询。
  • 如何使用导航属性?
  • A CarMake 相当于品牌权(丰田、本田、福特等)和 CarModel 模型(塔科马、思域、福克斯等)对吗?在这种情况下,这种关系应该是一对多的,因为一个品牌可以有多个模型,但一个模型只能由 1 个“品牌”制作。
  • @Jefferson:通过指定表之间的外键关系。 docs.microsoft.com/en-us/ef/ef6/fundamentals/relationships
  • 我使用的模型有三个表映射表 CarsandModel 有两个键?

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


【解决方案1】:

当使用实体框架时,人们倾向于自己(分组)加入表,而改用ICollections 会更容易。

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

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

CarMakesCarModels 之间的关系似乎是多对多:每个CarMake 有零个或多个CarModels,每个CarModel 由零个或多个CarMakes 组成。

在关系数据库中,多对多关系是使用联结表实现的。您的类CarsAndModel 代表此联结表中的一行。但是,当使用实体框架时,您不需要提及联结表。当您正确设计类时,实体框架会识别您的表之间的关系并为其创建适当的连接表。

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;}
}

在实体框架中,表的列由非虚拟属性表示。虚拟属性表示表之间的关系(一对多,多对多,...)

为了完整性,DbContext:

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

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

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

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

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

要求:给我 CarModel,每个都有他们的 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 知道您的多对多关系,并将为您创建正确的(组)连接。

【讨论】:

    猜你喜欢
    • 2021-07-21
    • 2019-05-23
    • 2013-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-23
    • 2019-03-16
    • 1970-01-01
    相关资源
    最近更新 更多