我有一个这样的主表工作区:
Description Date Timespend
TH work x 2018-12-28 3 hrs
NL work y 2018-12-28 2 hrs
UK work z 2018-12-30 5 hrs
和一张带客户的桌子
CustomerNo SearchTerms
C0001 Germany DEU DE
C0002 Netherlands NLD NL
C0003 United Kingdom UK
现在,我想为我的报告编写一个linq查询,该查询将显示带有customerNo的主表(如果可以找到的话)。 在SQL中,我会写类似
SELECT workspend.*,CustomerNo FROM workspend w
OUTER APPLY (SELECT top 1 * from customers c
WHERE c.SearchTerms LIKE '% ' + SUBSTRING(w.Description,1,2)) x
WHERE w.Date BETWEEN '2018-12-28' AND '2018-12-29'
结果将是
Description Date Timespend CustomerNo SearchTerms
TH work x 2018-12-28 3 hrs NULL NULL
NL work y 2018-12-28 2 hrs C0002 Netherlands NLD NL
在linq中可能吗? 预先感谢
答案 0 :(得分:0)
希望我已正确理解您的问题。您可以将GroupJoin与“自定义比较器”结合使用以实现结果。
例如,对于数据
var listMain = new List<MainTable>{
new MainTable{Description = "TH work x", Date = new DateTime(2018,12,28), TimeSpend = "3 hrs"},
new MainTable{Description = "NL work x", Date = new DateTime(2018,12,29), TimeSpend = "2 hrs"},
new MainTable{Description = "UK work x", Date = new DateTime(2018,12,30), TimeSpend = "5 hrs"},
};
var listCustomers = new List<Customers>
{
new Customers{CustomerNo="C0001", SearchTerms = "Germany DEU DE"},
new Customers{CustomerNo="C0002", SearchTerms = "Netherlands NLD NL"},
new Customers{CustomerNo="C0003", SearchTerms = "United Kingdom UK"},
};
MainTable和Customer定义为
public class MainTable
{
public string Description{get;set;}
public DateTime Date{get;set;}
public string TimeSpend {get;set;}
}
public class Customers
{
public string CustomerNo{get;set;}
public string SearchTerms{get;set;}
}
您可以使用Linq作为查询
var result = listMain.Where(x=>x.Date >= new DateTime(2018,12,28) && x.Date<new DateTime(2018,12,30)).GroupJoin(listCustomers,
x=>x.Description,
y=>y.SearchTerms,
(x,y)=> new {Main= x, Customers = y},
new ContainsEqualityComparer())
.Select(g=> new
{
Description = g.Main.Description,
Date=g.Main.Date,
TimeSpend=g.Main.TimeSpend,
CustomerNo=g.Customers.Any() ? g.Customers.First().CustomerNo: null,
SearchTerms=g.Customers.Any() ? g.Customers.First().SearchTerms:null
});
CustomEqualityComparer定义为
class ContainsEqualityComparer: IEqualityComparer<string>
{
public bool Equals(string right, string left)
{
return right.Contains(left.Substring(0,2));
}
public int GetHashCode(string obj) { return 0; }
}
输出如下所示
答案 1 :(得分:0)
这是我的翻译。 LINQ to SQL会将其转换为OUTER APPLY
:
var ans = from w in workspend
where DateTime.Parse("2018-12-28") <= w.Date && w.Date <= DateTime.Parse("2018-12-29")
from c in (from cs in customers where cs.SearchTerms.LastIndexOf(w.Description.Substring(0, 2)) == cs.SearchTerms.Length-2 select cs).Take(1).DefaultIfEmpty()
select new {
w,
c.CustomerNo
};
不幸的是,如果您使用服务器值(很容易输入),LINQ to SQL / Entities无法转换Contains
或EndsWith
,因此必须使用{{1} }进行伪造。
您还可以使用子查询,该子查询将转换为LastIndexOf
中的SQL子查询:
SELECT