EF Core中Contains方法无法被翻译,求问题原因及解决方案
EF Core查询Contains无法翻译的解决方案
你的问题出在EF Core无法将自定义实体类型的Contains操作转换为SQL查询——它没法识别EntityUserIdentityProvider对象的相等逻辑,没办法在数据库层面做匹配。
解决思路是先把uniqueUsers转换成EF Core能识别的简单组合类型集合,再用对应的条件做过滤:
- 先提取
uniqueUsers里的LoginProvider和ProviderKey,转换成值元组列表 - 在
Where条件里用元组匹配,替代原来的实体对象Contains - 最后生成字典时再把组合字段转回
EntityUserIdentityProvider作为键
修改后的代码如下:
// 先把uniqueUsers转换成EF Core可识别的元组集合 var targetPairs = uniqueUsers.Select(u => (u.LoginProvider, u.ProviderKey)).ToList(); var userProviders = _userLoginRepository.GetAll() .Where(ul => targetPairs.Contains((ul.LoginProvider, ul.ProviderKey))) .Select(ul => new { ul.LoginProvider, ul.ProviderKey, ul.UserId }) .ToList() .ToDictionary( k => new EntityUserIdentityProvider(k.LoginProvider, k.ProviderKey), v => v.UserId );
另外也可以用匿名类型集合来实现,效果一样:
var targetPairs = uniqueUsers.Select(u => new { u.LoginProvider, u.ProviderKey }).ToList(); var userProviders = _userLoginRepository.GetAll() .Where(ul => targetPairs.Any(p => p.LoginProvider == ul.LoginProvider && p.ProviderKey == ul.ProviderKey)) .Select(ul => new { ul.LoginProvider, ul.ProviderKey, ul.UserId }) .ToList() .ToDictionary( k => new EntityUserIdentityProvider(k.LoginProvider, k.ProviderKey), v => v.UserId );
如果你的EntityUserIdentityProvider重写了Equals和GetHashCode方法,也可以尝试在客户端先查询所有数据再过滤,但这种方式会把全表数据加载到内存,数据量大的时候不推荐:
var userProviders = _userLoginRepository.GetAll() .ToList() // 先把所有数据加载到内存 .Where(ul => uniqueUsers.Contains(new EntityUserIdentityProvider(ul.LoginProvider, ul.ProviderKey))) .ToDictionary( k => new EntityUserIdentityProvider(k.LoginProvider, k.ProviderKey), v => v.UserId );
内容的提问来源于stack exchange,提问作者Lasse O
相关产品推荐
相关产品推荐

