Mic*_*kel 10 c# linq linq-to-entities entity-framework join
我有这个LINQ查询:
// types...
LinkedList<WeightedItem> itemScores = new LinkedList<WeightedItem>();
var result = from i in _ctx.Items
join s in itemScores on i.Id equals s._id
orderby s._score descending
select new ItemSearchResult(i, s._score);
// this fails:
return result.ToList();
Run Code Online (Sandbox Code Playgroud)
哪个生成此错误:
无法创建类型为'System.Collections.Generic.IEnumerable`1'的常量值.
在此上下文中仅支持原始类型(例如Int32,String和Guid').
[编辑]以下代码WeightedItem:
public class WeightedItem
{
public int _id;
public decimal? _score;
public WeightedItem(int id, decimal? score)
{
_id = id;
_score = score;
}
}
Run Code Online (Sandbox Code Playgroud)
你能看出我做错了什么吗?代码编译完美,_ctx.Items和itemScores都包含正确的值.
Jon*_*eet 21
是的,它编译得很好 - 问题是它无法将其转换为SQL.当您引用"本地"值时,实体框架必须在需要创建SQL查询时确定如何处理它们.它基本上无法应对内存中集合和数据库表之间的连接.
可能有用的一件事就是使用Contains.我不知道是否LinkedList<T>会为此工作,但我相信List<T>,至少在LINQ to SQL中:
List<int> requiredScoreIds = itemScores.Select(x => x._id).ToList();
var tmp = (from i in _ctx.Items
where requiredScoreIds.Contains(i.Id)
orderby s._score descending
select i).AsEnumerable();
// Now do the join in memory to get the score
var result = from i in tmp
join s in itemScores on i.Id equals s._id
select new ItemSearchResult(i, s._score);
Run Code Online (Sandbox Code Playgroud)
现在,它正在进行内存中查询的连接,这在某种程度上是不必要的.您可以改为使用字典:
List<int> requiredScoreIds = itemScores.Select(x => x._id).ToList();
var tmp = (from i in _ctx.Items
where requiredScoreIds.Contains(i.Id)
orderby s._score descending
select i).AsEnumerable();
// Create a map from score ID to actual score
Dictionary<int, decimal?> map = itemScores.ToDictionary(x => x._id,
x => x._score);
var result = tmp.Select(i => new ItemSearchResult(i, map[i.Id]));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10542 次 |
| 最近记录: |