我有以下SQL:
select *
from [dbo].[CustomField] cf
left outer join [dbo].[CustomFieldDataItem] cd on cd.CustomFieldId = cf.Id and cd.OutsideId = 180
where cf.AnotherId = 1
我想用C#Lambda编写它,但我的代码仅显示具有数据项的自定义字段的数据项-我想查看所有自定义字段以及它们是否具有数据项-到目前为止,我已经做到了:
var myQuery = _db.CustomFields
.Where(c => c.AnotherId == 1)
.Join(_db.CustomFieldDataItems, cf => cf.Id, cd => cd.CustomFieldId, (cf, cd) => new { cf, cd })
.Where(f => f.cd.OutsideId == 180)
.Select(z => new CustomFieldModel
{
CustomFieldId = z.cf.Id,
Name = z.cf.Name,
DataValue = z.cd.DataValue
}).ToList()
我不知道将OutsideId where子句放在哪里,该子句实际上应该是联接的一部分
答案 0 :(得分:2)
在Linq中,您真的很少需要加入:
var myQuery = _db.CustomFields
.Where(c => c.AnotherId == 1)
.Select(cf => new CustomFieldModel
{
CustomFieldId = cf.Id,
Name = cf.Name,
DataValue = cf.cd.Any(cd => cd.OutSideId == 180)
? cf.cd.First(cd => cd.OutSideId == 180).DataValue
: (<type?>)null;
}).ToList();
在LinqToSQL中,这将生成类似以下的SQL:
DECLARE @p0 int = 1;
DECLARE @p1 Int = 180;
DECLARE @p2 Int = 180;
SELECT [t0].[CustomFieldId], [t0].[Name],
(CASE
WHEN EXISTS(
SELECT NULL AS [EMPTY]
FROM [CustomFieldDataItems] AS [t1]
WHERE ([t1].[OutsideID] = @p1) AND ([t1].[CustomFieldID] = [t0].[ID])
) THEN (
SELECT [t3].[DataValue]
FROM (
SELECT TOP (1) [t2].[DataValue]
FROM [CustomFieldDataItems] AS [t2]
WHERE ([t2].[OutsideID] = @p2) AND ([t2].[CustomFieldID] = [t0].[ID])
) AS [t3]
)
ELSE NULL
END) AS [DataValue]
FROM [CustomFields] AS [t0]
WHERE [t0].[AnotherId] = @p0
这实际上不会在原始SQL中产生结果(我使用First来获取DataValue,这意味着您不会以1-Many的形式获得结果)。
然后,我们可以使用此优化版本中的代码进行重写,该优化版本还会产生您原来的结果(不确定是否要重复CustomFields中的行-您的SQL会这样做):
var myQuery = (from cf in CustomFields
from cd in cf.CustomFieldDataItems.Where(d => d.OutsideId==180).DefaultIfEmpty()
where cf.AnotherId == 1
select new CustomFieldModel
{
CustomFieldId = cf.Id,
Name = cf.Name,
DataValue = cd == null?(int?)null:cd.DataValue,
AnotherValue = cd == null?(<typeName?>)null:cd.AnotherValue,
}).ToList();
生成的SQL看起来像:
DECLARE @p0 Int = 1;
DECLARE @p1 Int = 180;
SELECT [t0].[CustomFieldId], [t0].[Name],
(CASE
WHEN [t2].[test] IS NULL THEN NULL
ELSE [t2].[DataValue]
END) AS [DataValue],
(CASE
WHEN [t2].[test] IS NULL THEN NULL
ELSE [t2].[AnotherValue]
END) AS [AnotherValue]
FROM [CustomFields] AS [t0]
LEFT OUTER JOIN (
SELECT 1 AS [test], [t1].[DataValue], [t1].[CustomFieldID], [t1].[AnotherValue], [t1].[OutsideId]
FROM [CustomFieldDataItems] AS [t1]
) AS [t2] ON ([t2].[OutsideId] = @p0) AND ([t2].[CustomFieldID] = [t0].[ID])
WHERE [t0].[AnotherId] = @p1;
编辑:对此进行进一步的思考,可以将其简化为:
var myQuery = (from cf in CustomFields
from cd in cf.CustomFieldDataItems.Where(d => d.OutsideId==180).DefaultIfEmpty()
where cf.AnotherId == 1
select new CustomFieldModel
{
CustomFieldId = cf.Id,
Name = cf.Name,
DataValue = (int?)cd.DataValue,
AnotherValue = (<typeName?>)cd.AnotherValue,
}).ToList();
这将生成类似SQL的
DECLARE @p0 Int = 180;
DECLARE @p1 Int = 1;
SELECT [t0].[CustomFieldId], [t0].[Name],
[t1].[DataValue], [t1].[AnotherValue]
FROM [CustomFields] AS [t0]
LEFT OUTER JOIN [CustomFieldDataItems] AS [t1]
ON ([t1].[OutSideId] = @p0) AND ([t1].[CustomFieldID] = [t0].[ID])
WHERE [t0].[AnotherId] = @p1;
几乎与原始版本相同。
只需以“ lambda”形式填写即可:
var myQuery = _db.CustomFields
.Where (cf => cf.AnotherId == 1)
.SelectMany (
cf => cf.CustomFieldDataItems.Where (cd => (cd.OutsideId == (Int32?)180)).DefaultIfEmpty(),
(cf, cd) => new CustomFieldModel
{
CustomFieldId = cf.Id,
Name = cf.Name,
DataValue = (int?)cd.DataValue,
AnotherValue = (<typeName?>)cd.AnotherValue,
}
).ToList();
答案 1 :(得分:0)
尝试.DefaultIfEmpty()
var myQuery = _db.CustomFields
.Where(c => c.AnotherId == 1)
.Join(_db.CustomFieldDataItems.DefaultIfEmpty(), cf => cf.Id, cd => cd.CustomFieldId, (cf, cd) => new { cf, cd })
.Where(f => f.cd.OutsideId == 180)
.Select(z => new CustomFieldModel
{
CustomFieldId = z.cf.Id,
Name = z.cf.Name,
DataValue = z.cd.DataValue
}).ToList()
答案 2 :(得分:0)
如果您具有导航属性,则可以这样:
pandoc --columns=80 -o output.pdf ProjectDescription.md
“包含”是数据库t上的“左外连接”
编辑:已更改包含lambda
答案 3 :(得分:-1)
响应所有@Cetin Basoz的工作,我能够在Lambda中使用LinqPad获得解决方案-代替Join,在此示例中,我需要使用SelecctMany():
File file = new File("/Users/anvita.pandey/Desktop/file upload/KPSL/kpsl_n67_fatp_evt_site13.xlsx");
StringSelection stringSelection= new StringSelection(file.getAbsolutePath());
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_META);
robot.keyPress(KeyEvent.VK_TAB);
robot.keyRelease(KeyEvent.VK_META);
robot.keyRelease(KeyEvent.VK_TAB);
robot.delay(500);
//System.out.println("changing window hanlder ");
//driver.switchTo().window(driver.getWindowHandle());
//Open Goto window
robot.keyPress(KeyEvent.VK_META);
robot.keyPress(KeyEvent.VK_SHIFT);
robot.keyPress(KeyEvent.VK_G);
robot.keyRelease(KeyEvent.VK_META);
robot.keyRelease(KeyEvent.VK_SHIFT);
robot.keyRelease(KeyEvent.VK_G);
//Paste the clipboard value
robot.keyPress(KeyEvent.VK_META);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_META);
robot.keyRelease(KeyEvent.VK_V);
//Press Enter key to close the Goto window and Upload window
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
robot.delay(500);
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);