【问题标题】:Linq-To-Entities using method to select new objectLinq-To-Entities 使用方法选择新对象
【发布时间】:2015-11-09 10:54:16
【问题描述】:

我尝试在我的应用程序中多次使用相同的选择查询。 例如我有这个选择语句:

 _db.tbl_itembundlecontents
                    .Select(z => new SingleItemDTO
                    {
                        amount = z.amount,
                        id = z.id,
                        position = z.position,
                        contentType = new BasicMaterialDTO
                        {
                            id = z.tbl_items.id,
                            img = z.tbl_items.tbl_material.img,
                            name = z.tbl_items.tbl_material.name,
                            namekey = z.tbl_items.tbl_material.namekey,
                            info = z.tbl_items.tbl_material.info,
                            weight = z.tbl_items.tbl_material.weight
                        }
                    });

但我也有这个:

 _db.tbl_itembundle
                .Where(x => x.type == 2)
                .Select(y => new ItemBundleDTO
                {
                    name = y.name,
                    namekey = y.namekey.
                    contents = y.tbl_itembundlecontents
                    .Select(z => new SingleItemDTO
                    {
                        amount = z.amount,
                        id = z.id,
                        position = z.position,
                        contentType = new BasicMaterialDTO
                        {
                            id = z.tbl_items.id,
                            img = z.tbl_items.tbl_material.img,
                            name = z.tbl_items.tbl_material.name,
                            namekey = z.tbl_items.tbl_material.namekey,
                            info = z.tbl_items.tbl_material.info,
                            weight = z.tbl_items.tbl_material.weight
                        }
                    })
                });

如您所见,我在两个 linq select 语句中使用完全相同的代码(用于 SingleItemDTO)。有没有办法分离我的第一个选择语句的代码(没有得到 NotSupportedException)并再次重用它?我的第二个查询应该是这样的:

_db.tbl_itembundle
                .Where(x => x.type == 2)
                .Select(y => new ItemBundleDTO
                {
                    name = y.name,
                    namekey = y.namekey.
                    contents = y.tbl_itembundlecontents.ToDTO()
                });

【问题讨论】:

    标签: c# asp.net-mvc entity-framework linq linq-to-entities


    【解决方案1】:

    这是可能的,但方式有点不寻常。

    创建一个辅助方法并像这样移动第一个查询的选择器部分

    static Expression<Func<[tbl_itembundlecontents entity type], SingleItemDTO>> ToSingleItemDTO()
    {
        return z => new SingleItemDTO
        {
            amount = z.amount,
            id = z.id,
            position = z.position,
            contentType = new BasicMaterialDTO
            {
                id = z.tbl_items.id,
                img = z.tbl_items.tbl_material.img,
                name = z.tbl_items.tbl_material.name,
                namekey = z.tbl_items.tbl_material.namekey,
                info = z.tbl_items.tbl_material.info,
                weight = z.tbl_items.tbl_material.weight
            }
        };
    }
    

    现在第一个查询可以是这样的

    _db.tbl_itembundlecontents.Select(ToSingleItemDTO());
    

    第二个像这样

    _db.tbl_itembundle
        .Where(x => x.type == 2)
        .Select(y => new ItemBundleDTO
        {
            name = y.name,
            namekey = y.namekey.
            contents = y.tbl_itembundlecontents.AsQueryable().Select(ToSingleItemDTO())
        });
    

    注意导航属性后面的AsQueryable(),这是使其工作的必要部分。

    【讨论】:

      【解决方案2】:

      这样的?

      public static class HelperExtension
      {
          public static IEnumerable<SingleItemDTO> ToDto(this IEnumerable<Tbl_itembundlecontents> items)
          {
              return items.Select(z => z.ToDto());
          }
      
          public static SingleItemDTO ToDto(this Tbl_itembundlecontents z)
          {
              return new SingleItemDTO
              {
                  amount = z.amount,
                  id = z.id,
                  position = z.position,
                  contentType = new BasicMaterialDTO
                  {
                      id = z.tbl_items.id,
                      img = z.tbl_items.tbl_material.img,
                      name = z.tbl_items.tbl_material.name,
                      namekey = z.tbl_items.tbl_material.namekey,
                      info = z.tbl_items.tbl_material.info,
                      weight = z.tbl_items.tbl_material.weight
                  }
              };
          }
      }
      

      【讨论】:

      • 这会抛出同样的异常
      • 啊抱歉,是的,是 linq 到 sql 的转换引发了异常,我知道这有点作弊,但你可以 .Where(x => x.type == 2).ToList()然后做投影
      • 是的,打电话给ToList() 可能是最简单的。然而,这意味着生成的 SQL SELECT 可能包含不必要的字段,并且进一步的导航属性访问(在映射期间)将调用额外的查询(使用延迟加载机制)。
      • 正如@haim770 已经提到的,我不想SELECT 不必要的字段。但LinqKit 可能是我正在寻找的扩展名。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多