linq-to-sql - LINQ : Expression. 调用(类型(可查询), "Select"

标签 linq-to-sql lambda projection

我正在尝试创建一个小型“automapper-esq”实用程序,它将采用 LinqToSql 实体并将其映射到“投影类”。

到目前为止,我有这样的东西:

class Entity
{
    public int ID { get; set; }
    public string WantedProperty { get; set; }
    public string UnWantedPropertyData { get; set; }
    ...More Unwanted Properties...
    public IEnumerable<ChildEntity> ChildEntities { get; set; }
}

class EntityProjection
{
    public int ID { get; set; }
    public string WantedProperty { get; set; }
    public IEnumerable<ChildEntityProjection> ChildEntities { get; set; }
}

class ChildEntityProjection
{
    public int ID { get; set; }
    public string WantedProperty { get; set; }
    public string UnWantedPropertyData { get; set; }
    ...More Unwanted Properties...
}


var results = context.Table.Select(ProjectionHelper.BuildProjection<Entity,EntityProjection>());

BuildProjection 返回的地方:

Expression<Func<TSource, TResult>>

这实际上创建了一个像这样的 lambda:

A => new EntityProjection() { ID = A.ID, WantedProperty = A.WantedProperty }

现在是棘手的部分......我也希望能够投影“父”实体的关联属性。基本上我需要的是得到这样的东西:

A => new EntityProjection() {
  ID = A.ID,
  WantedProperty = A.WantedProperty,
  ChildEntities = A.ChildEntities.Select(B => new ChildEntityProjection {
    ID = B.ID,
    WantedProperty = B.WantedProperty
  }
}

我已经得到了这部分:

A => new EntityProjection() {
  ID = A.ID,
  WantedProperty = A.WantedProperty,
  ChildEntities = System.Collections.Generic.List1[ChildEntity].Select(B => new ChildEntityProjection {
    ID = B.ID,
    WantedProperty = B.WantedProperty
  }
}

这样做:

IQueryable<ChildEntity> list = new List<ChildEtity>().AsQueryable();
Expression _selectExpression = Expression.Call(
  typeof(Queryable),
  "Select",
  new Type[] { typeof(ChildEntity), typeof(ChildEntityProjection) },
  Expression.Constant(list),
  _nestedLambda);

这就是我目前被困的地方......当我试图用其他一些代表属性实际数据类型的表达式替换 Expression.Constant(list) 时,我有点困惑,这样“System.Collections. Generic.List1[ChildEntity].Select(B=>..."将替换为 "A.ChildEntities.Select(B=>..."

有什么想法吗?

最佳答案

我一直在寻找如何使用表达式(正确的术语?)来做到这一点,我最终弄明白了。

我不得不改变这个:

IQueryable<ChildEntity> list = new List<ChildEtity>().AsQueryable(); 
Expression _selectExpression = Expression.Call( 
  typeof(Queryable), 
  "Select", 
  new Type[] { typeof(ChildEntity), typeof(ChildEntityProjection) }, 
  Expression.Constant(list), 
  _nestedLambda); 

为此:

MethodInfo selectMethod = null;
foreach (MethodInfo m in typeof(Enumerable).GetMethods().Where(m => m.Name == "Select"))
  foreach (ParameterInfo p in m.GetParameters().Where(p => p.Name.Equals("selector")))
    if (p.ParameterType.GetGenericArguments().Count() == 2)
      selectMethod = (MethodInfo)p.Member;

var _selectExpression = Expression.Call(
  null,
  selectMethod.MakeGenericMethod(new Type[] { typeof(ChildEntity), typeof(ChildEntityProjection) }),
  new Expression[] { _myPropertyExpression, _myFuncExpression });

希望这对其他人有帮助...

关于linq-to-sql - LINQ : Expression. 调用(类型(可查询), "Select",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3920126/

相关文章:

MySql Null DateTime 和 MS.net 表现不佳

asp.net-mvc-3 - 不能将 null 值分配给 System.DateTime 类型的成员

c# - 具有许多可选参数的过滤器不起作用

python - Lambda 替换

javascript - javascript/jquery 中的 lambda 包装器——为什么?

image-processing - 如何将球面坐标转换为等距柱状投影坐标?

c# - 使用 Linq-to-sql 在 sql-server 中存储枚举

python - OpenCV unproject 2D 指向具有已知深度 `Z` 的 3D

Angular 2 : ng-content attributes passing to child component

php - 使类的静态成员成为函数(闭包)不起作用