【问题标题】:EntityFramework Core get multiple results after joinEntityFramework Core 加入后得到多个结果
【发布时间】:2020-01-17 15:05:41
【问题描述】:

数据库有表机器、轮子、特征。 1个汽车记录包括4个车轮记录和几个特征。在数据库中,它看起来像这样:

我想获取关于汽车的最后 5 个条目,包括一组完整的参数数据和车轮信息。我想在一个请求中获取所有数据。

 var result = (from Machines in db.Machines.Where(x => x.param == 2) orderby Machines.ID descending
                      join wheel in db.Wheels on Machines.ID equals wheel.MachineId
                      join param in db.Characteristcs on Machines.ID equals param.MachineId
                      select new { Machines, param, wheel } 
                      ).Take(5).ToList();

但它只返回一个车轮记录和一个特征。

【问题讨论】:

  • 不要使用连接。在实体之间使用适当的关系并让 ORM 生成连接。这就是它的工作
  • 你的模型类代码和实际结果截图是什么?我根据您的屏幕截图和代码创建了一个测试演示,它得到了异常结果。你可以参考下面我的回复。
  • @TiyebM *"在不需要预定义导航规则的情况下创建和执行查询的想法很强大,应该由框架本身解决;不仅仅是包含。`导航属性的想法要强大得多,并且总是比手动连接更受欢迎,尤其是对于在这种情况下表示关系的事物。因为它们不仅仅是支持Include。在查询中使用时,它们允许 ORM 创建连接,开发人员使用更自然的面向对象方法集中查询逻辑。连接是 RDBMS (SQL) 功能,并且...
  • ...它们存在于 LINQ 中的唯一原因是因为 LINQ to Objects 需要它们来有效地执行相关操作。 EF Core 根本不需要它们 - 相关的 WhereDefaultIfEmpty 足以在需要时生成适当的 SQL 连接。

标签: asp.net entity-framework asp.net-core .net-core entity-framework-core


【解决方案1】:
  1. 在 SQL Server 中,创建机器与 Wheels 和 Characteristic 表的关系。
  2. 重新运行 scaffolding-dbcontext 以更新您的 EF dbcontext 和模型
  3. 使用包含 linq。 var result = db.Machines.Where(x => x.Id == 2).Include(x => x.Wheels).Include(x => x.Characteristics);

See screenshot

【讨论】:

    【解决方案2】:

    我认为你应该先看看你的模型是否为你需要的实体定义了导航属性:

    public class Machine {
    
      public int ID {get;set;}
      //...
      //Navigation Properties
      public IList<Wheel> Wheels {get;set;}
      public IList<Charateristic> Charateristics {get;set;}
    
    }
    

    如果是这种情况,您的查询将是:

    var query= context.Machines.Include(m=> m.Wheels)
                               .Include(m=>m.Charateristics)
                               .Where(x => x.param == 2)
                               .Take(5)
                               .ToList();
    

    Include 方法有助于构建查询,从相关表中获取您需要的数据。

    如果你没有定义导航属性,我强烈建议你这样做,你可以这样做group joins

    var query=  from m in context.Machines
                join c in context.Charateristics on m.Id equals c.MachineId into gc
                join w in context.Wheels on m.Id equals w.MachineId into gw
                select new {Machine= m, Wheels= gw, Charateristics=gc };
    
    var result= query.Take(5).ToList();
    

    【讨论】:

    • generalEF6 中的好答案,但 EF Core(直到现在,将看到下一个版本会发生什么)总是有自己的处理方法LINQ 查询翻译。这里的“小”问题是 EFC 3.x - 5.x 不支持组连接,因此第二部分根本不起作用(运行时异常)。
    【解决方案3】:

    在 EF Core 中,您可以参考relationshipload raleted data 了解更多详情。

    这是我的工作演示:

    模型

    public class Machines
    {
        public int Id { get; set; }
        public string Description { get; set; }
        public string Color { get; set; }
        public int Weight { get; set; }
        public int Param { get; set; }
    }
    public class Characteristics
    {
        public int Id { get; set; }
        public string Parameter { get; set; }
        public string Value { get; set; }
        public string Description { get; set; }
    
        public int MachineId { get; set; }
    }
    public class Wheels
    {
        public int Id { get; set; }
        public int Radius { get; set; }
        public int Weight { get; set; }
        public int MachineId { get; set; }
    }
    

    控制器

    public IActionResult GetCars()
    {
            var collection = (from Machines in _context.Machines.Where(x => x.Param == 2)
                          join wheel in _context.Wheels on Machines.Id equals wheel.MachineId
                          join param in _context.Characteristics on Machines.Id equals param.MachineId
                          select new { Machines, param, wheel }
                      ).ToList();
    
            //get the last 5 entries about cars
            var result= collection.Skip(Math.Max(0, collection.Count() - 5)).ToList();
            return new JsonResult(result);
    }
    

    【讨论】:

    • 这会将整个集合(表)加载到内存中,以获取所需的 5 个项目。一般不要使用这样的代码(它只适用于字段少的小表),根据使用的 EFC 版本,有更好的解决方案。
    猜你喜欢
    • 2015-09-05
    • 2019-05-02
    • 2011-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多