无法将Lambda表达式转换为委托类型(无引用错误)求助
嘿,这个问题我之前也碰到过,核心就是Repository的方法签名不匹配,导致编译器找不到你要调用的那个Get方法,咱们一步步来解决:
1. 为什么会出现这个错误?
你现在的代码里调用的是带lambda表达式的Get:
internal virtual GlobalTable GetGlobalTableById(int newTableId) { return UnitOfWork.GlobalTableRepository.Get( x => x.NewTableId == newTableId).FirstOrDefault(); }
这里的Get需要接受一个Func<GlobalTable, bool>类型的参数,但你在IGlobalTableRepository里只定义了接受int的Get方法:
GlobalTable Get(int newTableId);
两个方法的签名完全不一样,编译器找不到对应重载,就会模糊推断出需要object Get(Func<object, object> p);这个奇怪的方法,这就是错误的根源。
另外,System.Data.Entity灰显是因为你的代码里没有直接用到这个命名空间下的东西,比如如果你的Repository是基于EF的,但你没直接调用EF的类型或扩展方法,IDE就会标灰提示你这个引用是冗余的,不用管它或者直接删掉都行。
2. 两种修复方案任你选
方案一:直接用已定义的方法(最简单)
既然你已经写了接受int参数的Get(int newTableId),那直接传入参数就好,没必要用lambda绕一圈:
internal virtual GlobalTable GetGlobalTableById(int newTableId) { return UnitOfWork.GlobalTableRepository.Get(newTableId); }
这样代码更简洁,也完全匹配你现有的Repository接口。
方案二:扩展Repository支持lambda查询(更灵活)
如果你需要Repository支持更复杂的查询,可以修改IGlobalTableRepository,添加对应的方法:
子方案2.1:添加带lambda的Get重载
在IGlobalTableRepository里加上:
IEnumerable<GlobalTable> Get(Func<GlobalTable, bool> predicate);
然后在你的Repository实现类(比如GlobalTableRepository)里实现这个方法,假设你用的是EF:
public IEnumerable<GlobalTable> Get(Func<GlobalTable, bool> predicate) { return _dbContext.GlobalTables.Where(predicate); }
这样你原来的调用代码就能正常工作了。
子方案2.2:提供IQueryable入口(推荐)
更专业的做法是给Repository加一个返回IQueryable<GlobalTable>的方法,这样能利用EF的延迟加载和查询优化:
// 在IGlobalTableRepository中添加 IQueryable<GlobalTable> GetAll();
然后调用代码改成:
internal virtual GlobalTable GetGlobalTableById(int newTableId) { return UnitOfWork.GlobalTableRepository.GetAll() .FirstOrDefault(x => x.NewTableId == newTableId); }
这种方式不仅能解决当前问题,以后复杂查询也能直接用Linq写,非常灵活。
3. 额外要检查的点
- 确认你的
UnitOfWork注入的是你自己定义的IGlobalTableRepository实现,别不小心用了默认的基类或者其他实现,导致方法不匹配。 - 如果
System.Data.Entity确实没用,直接删掉这个命名空间引用就行,减少冗余。
内容的提问来源于stack exchange,提问作者Keith

