gpt4 book ai didi

linq - 使用 LINQ 动态映射(或构造投影)

转载 作者:行者123 更新时间:2023-12-01 11:08:24 25 4
gpt4 key购买 nike

我知道我可以使用 LINQ 使用投影映射两种对象类型:

var destModel = from m in sourceModel
select new DestModelType {A = m.A, C = m.C, E = m.E}

在哪里

class SourceModelType
{
string A {get; set;}
string B {get; set;}
string C {get; set;}
string D {get; set;}
string E {get; set;}
}

class DestModelType
{
string A {get; set;}
string C {get; set;}
string E {get; set;}
}

但是如果我想做一些类似泛型的东西来做这件事,我不知道我正在处理的两种具体类型。所以它会走“Dest”类型并匹配匹配的“Source”类型..这可能吗?此外,为了实现延迟执行,我希望它只返回一个 IQueryable。

例如:

public IQueryable<TDest> ProjectionMap<TSource, TDest>(IQueryable<TSource> sourceModel)
{
// dynamically build the LINQ projection based on the properties in TDest

// return the IQueryable containing the constructed projection
}

我知道这很有挑战性,但我希望并非不可能,因为它将为我省去大量模型和 View 模型之间的显式映射工作。

最佳答案

你必须生成一个表达式树,但是一个简单的树,所以并不难......

void Main()
{
var source = new[]
{
new SourceModelType { A = "hello", B = "world", C = "foo", D = "bar", E = "Baz" },
new SourceModelType { A = "The", B = "answer", C = "is", D = "42", E = "!" }
};

var dest = ProjectionMap<SourceModelType, DestModelType>(source.AsQueryable());
dest.Dump();
}

public static IQueryable<TDest> ProjectionMap<TSource, TDest>(IQueryable<TSource> sourceModel)
where TDest : new()
{
var sourceProperties = typeof(TSource).GetProperties().Where(p => p.CanRead);
var destProperties = typeof(TDest).GetProperties().Where(p => p.CanWrite);
var propertyMap = from d in destProperties
join s in sourceProperties on new { d.Name, d.PropertyType } equals new { s.Name, s.PropertyType }
select new { Source = s, Dest = d };
var itemParam = Expression.Parameter(typeof(TSource), "item");
var memberBindings = propertyMap.Select(p => (MemberBinding)Expression.Bind(p.Dest, Expression.Property(itemParam, p.Source)));
var newExpression = Expression.New(typeof(TDest));
var memberInitExpression = Expression.MemberInit(newExpression, memberBindings);
var projection = Expression.Lambda<Func<TSource, TDest>>(memberInitExpression, itemParam);
projection.Dump();
return sourceModel.Select(projection);
}

(在 LinqPad 中测试,因此是 Dump)

生成的投影表达式如下所示:

item => new DestModelType() {A = item.A, C = item.C, E = item.E}

关于linq - 使用 LINQ 动态映射(或构造投影),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2928757/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com