【问题标题】:Left join a queryable on multiple property on a non-generic queryable using Dynamic.Linq使用 Dynamic.Linq 在非泛型可查询对象上左连接多个属性的可查询对象
【发布时间】:2021-07-28 06:24:05
【问题描述】:

我有 2 个包含以下实体的可查询对象:

class Entity
{
    int Id { get;set; }
}

class ExtraField
{
   int EntityId { get;set; }
   string Key { get;set; }
   string Value {get;set; }
}

产生 2 个可查询项

IQueryable entities;
IQueryable extraFields;

一个实体可以有多个额外的字段。并非所有实体都包含相同数量的额外字段。因此,需要左连接。可查询的最终结果应导致以下结果:

Entity Id Extra field 1 Extra field 2 Extra field 3
1 value value value
2 value NULL NULL
3 NULL NULL NULL

在 SQL 中,我想创建某种 PIVOT 来创建上面的结果。但是,我想用 linq 来实现这一点。

因为一个实体可以有 x 个额外字段,所以我需要 x 个额外字段表上的联接。因为该字段并不总是存在,所以我需要一个 LEFT 连接。

我在 stackoverflow 和 Dynamic Linq 文档上花了几个小时,但无法找到有关如何使用带字符串语法的动态 linq 构建查询的答案。

我走了这么远:

entities.GroupJoin(extraFields, "Id", "EntityId", "new(outer.Id as Id, inner as ExtraFields)").SelectMany("ExtraFields.DefaultIfEmpty()", "new( what do i need to put here??  )");

使用通用的非动态 linq,我得到了这个工作。但是与此等效的 Dynamic Linq 是什么?

var result = from entity in entities
             from extraField in extraFields.Where(ef => ef.EntityId == entity.Id && ef.Key = "ExtraField1").DefaultIfEmpty()
             select new
             {
                 EntityId = entity.Id,
                 ExtraField = extraField.Value
             };

【问题讨论】:

  • 用 SQL 编写 PIVOT 查询并使用 Dapper 获取数据。容易得多。
  • 我确实在尝试创建一个支点。但我更愿意利用我还需要订购和跳过/服用的 linq 功能

标签: c# linq dynamic-linq dynamic-linq-core


【解决方案1】:

我猜你正在寻找如何加入。不清楚你希望看到什么

示例:

void Main()
{
    var entities = new List<Entity>() { new Entity() {Id = 1}};
    var extraFields = new List<ExtraField>() { 
        new ExtraField() {EntityId = 1, Key = "ExtraField1", Value="a"},
        new ExtraField() {EntityId = 1, Key = "ExtraField2", Value="b"}
        };
    
    var result = from entity in entities
                 from extraField in extraFields.Where(ef => ef.EntityId == entity.Id && ef.Key == "ExtraField1").DefaultIfEmpty()
                 select new
                 {
                     EntityId = entity.Id,
                     ExtraField = extraField.Value
                 };
                result.Dump("original");
    
    entities
        .GroupJoin(
                extraFields, 
                en => en.Id,
                ext => ext.EntityId,
                (en, ext) => new { entities = en, ExtraField = ext }
            )
            .Dump("join");
            
                
}

public class Entity
{
    public int Id { get; set; }
}

public class ExtraField
{
    public int EntityId { get; set; }
    public string Key { get; set; }
    public string Value { get; set; }
}


【讨论】:

  • 我正在寻找 Dynamic.Linq.Core 库的动态 linq 方法,因为我正在使用非泛型 IQueryable。因此,我无权访问类型化的属性
  • 我在寻找解决方案时发现了这篇文章。然而,给定的答案给出了一个错误。它说变量“内部”和“外部”在 SelectMany 中不可用。我需要在那里放什么?这就是我的问题所在。
猜你喜欢
  • 2013-07-20
  • 2017-03-27
  • 2016-05-29
  • 1970-01-01
  • 2012-07-16
  • 2021-05-16
  • 2020-02-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多