如何解决将 Expression<Func<T, bool>> 转换为另一个谓词表达式 Expression<Func<U, bool>>
我想将一个谓词表达式(Expression
using System;
using System.Linq;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using System.Reflection;
public class ItemEntity {
public int ItemId {set;get;}
public int ItemParentId {set;get;}
public int ItemName {set;get;}
}
public class Item {
public int Id{ set;get;}
public int ParentId{set;get;}
public int Name {set;get;}
}
public class Program
{
public static Item Convert(ItemEntity itemChild)
{
return new Item()
{
Id = itemChild.ItemId,ParentId = itemChild.ItemParentId,Name = itemChild.ItemName
};
}
public async Task<IList<ItemEntity>> SelectAsync(Expression<Func<ItemEntity,bool>> predicate)
{
// using Microsoft.EntityFrameworkCore;
// private readonly DbContext _context; // Injected globally by using Service.AddScoped<ItemContext>();
// return await _context.Set<ItemEntity>().AsNoTracking().Where(predicate).ToListAsync();
return await Task.Run(() => new List<ItemEntity>()); // actually return the result with matching predicate
}
public async Task<List<Item>> GetItems(Expression<Func<Item,bool>> expression)
{
MethodInfo convertMethod = ((Func<ItemEntity,Item>)Convert).Method;
var p = Expression.Parameter(typeof(ItemEntity));
var converted = Expression.Lambda<Func<ItemEntity,bool>>(
Expression.Invoke(expression,Expression.Convert(p,typeof(Item),convertMethod)),p);
IList<ItemEntity> res = await SelectAsync(converted);
var t = res.Select(x => Convert(x)).ToList();
return t;
}
public static void Main()
{
Program pr = new Program();
Func<Expression<Func<Item,bool>>,Task<List<Item>>> getItem = pr.GetItems;
var res = getItem.Invoke(x => x.Id.Equals(1));
Console.WriteLine("Hello World");
}
}
但我收到错误
无法翻译 LINQ 表达式 'DbSet()\r\n .Where(i => ((Item)i).Id.Equals(__Id_0))'。以可翻译的形式重写查询,或通过插入对“AsEnumerable”、“AsAsyncEnumerable”、“ToList”或“ToListAsync”的调用,显式切换到客户端评估。有关详细信息,请参阅 https://go.microsoft.com/fwlink/?linkid=2101038。
我无法正确理解它,根据我的理解,我使用 ToList() 进行客户端评估,但还提供了将 ItemEntity 转换为 Item 的方法。
我还有其他方法可以基于 ItemEntity 创建新的表达式树,然后在 DBSet 上查询吗? 任何帮助表示赞赏
使用的版本:
解决方法
尝试以下方法。主要思想是在具体化之前在预计的 DTO 上准确使用过滤器。
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
public class ItemEntity
{
public int ItemId { set; get; }
public int ItemParentId { set; get; }
public int ItemName { set; get; }
}
public class Item
{
public int Id { set; get; }
public int ParentId { set; get; }
public int Name { set; get; }
}
public class Program
{
public static Expression<Func<ItemEntity,Item>> ToItem()
{
return itemChild => new Item
{
Id = itemChild.ItemId,ParentId = itemChild.ItemParentId,Name = itemChild.ItemName
};
}
public Task<IList<Item>> SelectAsync(Expression<Func<Item,bool>> predicate)
{
return _context.Set<ItemEntity>()
.AsNoTracking()
.Select(ToItem())
.Where(predicate)
.ToListAsync();
//return Task.Run(() => new List<ItemEntity>().AsQueryable().Select(ToItem()).Where(predicate).ToList());
}
public async Task<IList<Item>> GetItems(Expression<Func<Item,bool>> expression)
{
var res = await SelectAsync(expression);
return res;
}
public static void Main()
{
var pr = new Program();
var res = pr.GetItems(x => x.Id == 1);
Console.WriteLine("Hello World");
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。