我正在尝试创建一个小的“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 =&gt; ...“将替换为”A.ChildEntities.Select(B =&gt; ...“
有什么想法吗?
答案 0 :(得分:7)
我正在寻找更多如何使用表达式(正确的术语?)来做到这一点,并且我最终确定了它。
我不得不改变这个:
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 });
希望这有助于其他人......
答案 1 :(得分:0)
这是一个建议的查询。你可能想要改变你的IEnumerable&lt;&gt;在EntityProjection中的列表&lt;&gt;避免懒惰负载(如果重要......)。无论如何,我希望这是有帮助的。
EntityProjection projection = context.Table
.Where(entity => entity.ID == 123)
.Select(entity => new EntityProjection()
{
ID = entity.ID,
WantedProperty = entity.WantedProperty,
ChildEntities = entity.ChildEntities
.Select(child => new ChildEntityProjection()
{
ID = child.EmployeeID,
WantedProperty = child.WantedProperty
})
.ToList()
})
.SingleOrDefault();