我有一个长的查询返回
Item {
DateTime entryDate
.....
}
我喜欢将此查询的结果与另一个表
结合起来Value {
DateTime date,
double value
}
如果entryDate> = CUTOFF,则取CUTOFF上的值,否则取entryDate上的值。换句话说,我想实现:
SELECT Item.*, Value.value WHERE
MIN( Item.entryDate, CUTOFF ) == Value.date
请原谅我的语法,但这就是主意。
编辑:经过一些试验和错误,我想出了这个linq-to-sql查询:
from iValue in Values
join iItem in ... (long query)
let targetDate = iItem.EntryDate > CUTOFF ? iItem.EntryDate : CUTOFF
where iValue.Date == targetDate
select new
{
iItem,
targetDate,
iValue
}
感谢您的帮助。
答案 0 :(得分:0)
yourLongQuery.Where(y => y.Item.entryDate == Value.date || CUTOFF == Value.date)
.Select(x => new {
entrydate = (x.Item.entryDate < CUTOFF ? x.Item.entryDate : CUTOFF),
/*rest of x.Item properties here */ ,
x.Value.date,
x.Value.value
});
过滤查询,将两个项目合并为一个项目并修改第一个项目
答案 1 :(得分:0)
这样如果entryDate&gt; = CUTOFF,则取CUTOFF上的值,否则 在entryDate上取值。换句话说,我想实现: SELECT Item。*,Value.value WHERE MAX(Item.entryDate,CUTOFF)== Value.date
这是自相矛盾的if entryDate >= CUTOFF then take the value on CUTOFF
实施,您需要MIN(Item.entryDate, CUTOFF)
,而不是MAX
。
话虽如此,您只想选择与查询的每个项目匹配的value.Value。每个项目都应查找与您的MAX(或我相信MIN)语句匹配的相关值。
query.Select(item =>
{
var matchingValue = Values.Single(v =>
v.date == Min(item.entryDate, CUTOFF));
return new { item, matchingValue.value };
});
这将返回IQueryable的匿名{ Item, double }
个对象。
如果您要求将其作为单个SQL语句执行,则需要进行一些重构。一个好的开始是将matchingValue
交换成一个声明。
query.Select(item => new { item, context.Values.Single(v =>
v.date == Min(item.entryDate, CUTOFF)).value });
我没有在我面前确认Visual Studio,但我不确定Math.Min
函数是否在LINQ-to-SQL中映射。我们假设它不是。
query.Select(item => new { item, context.Values.Single(v =>
v.date == (item.entryDate < CUTOFF ? item.entryDate : CUTOFF)).value });
我相信如果您使用.ToList()
执行该查询,将解析为单个查询,但在我面前有一些工具之前无法确认。使用SQL事件探查器进行测试以确定。
答案 2 :(得分:0)
鉴于您已从Item
查询中返回数据并且Value
表格相对较小,那么这是一个不错的方法:
var lookup = values.ToLookup(v => v.date, v => v.value);
var query =
from i in items
let c = i.entryDate < CUTOFF ? i.entryDate : CUTOFF
let v = lookup[c].FirstOrDefault()
select new
{
Item = i,
Value = v,
};
ToLookup
扩展程序非常有用且经常被忽略。