我希望LINQ查询有两个行为,取决于参数。
如果param = -1,则返回所有行
如果param> -1,返回选择行
这是我尝试过的。它模拟我如何在SQL服务器中编写它(如果param> -1,则使用where子句将其强制转换为内连接的左连接),但它的行为不同。它总是返回已过滤的行,就像RTA连接是内连接一样。
// Get attributes filtered to the template (-1 = all)
var result2 = from RA in ent.ReportAttributes
join FT in ent.FilterTypes on RA.FilterTypeID equals FT.FilterTypeID
join DS in ent.DataSources on RA.DataSourceID equals DS.DataSourceID
join RTA in ent.ReportTemplateAttributes.DefaultIfEmpty() on RA.AttributeID equals RTA.AttributeID
where templateID == -1 || (templateID != -1 && RTA.TemplateID == templateID)
select new HRFWeb.Models.ReportAttributeModel()
{
AttributeGroupID = RA.AttributeGroupID,
AttributeID = RA.AttributeID,
ParentID = RA.ParentID,
Name = RA.Name,
Alias = RA.Alias,
IsCalculated = RA.IsCalculated,
FilterTypeID = RA.FilterTypeID,
FilterType = FT.Name,
DataSourceID = RA.DataSourceID,
DBName = DS.DBName,
ServerName = DS.ServerName,
ServerIP = DS.ServerIP,
DataSourceTable = RA.DataSourceTable,
LogiDataType = RA.LogiDataType
};
为了进一步演示,这里是等效的SQL:
DECLARE @TemplateID INT = -1 -- Returns 53 rows (correct) SELECT * FROM dbo.ReportAttribute RA JOIN dbo.FilterType FT ON FT.FilterTypeID = RA.FilterTypeID JOIN dbo.DataSource DS ON DS.DataSourceID = RA.DataSourceID LEFT JOIN dbo.ReportTemplateAttribute RTA ON RTA.AttributeID = RA.AttributeID WHERE @TemplateID = -1 OR (@TemplateID > -1 AND RTA.TemplateID = @TemplateID) SET @TemplateID = 0 -- Returns 32 rows (correct) SELECT * FROM dbo.ReportAttribute RA JOIN dbo.FilterType FT ON FT.FilterTypeID = RA.FilterTypeID JOIN dbo.DataSource DS ON DS.DataSourceID = RA.DataSourceID LEFT JOIN dbo.ReportTemplateAttribute RTA ON RTA.AttributeID = RA.AttributeID WHERE @TemplateID = -1 OR (@TemplateID > -1 AND RTA.TemplateID = @TemplateID)
答案 0 :(得分:0)
试试这个。想法是在加入后过滤ReportTemplateAttributes。要进行左连接,需要into group
和select xxx from group.DefaultIfEmpty()
的组合。
var result2 = from RA in ent.ReportAttributes
join FT in ent.FilterTypes on RA.FilterTypeID equals FT.FilterTypeID
join DS in ent.DataSources on RA.DataSourceID equals DS.DataSourceID
join RTA in ent.ReportTemplateAttributes on RA.AttributeID equals RTA.AttributeID into g1
from g in g1
select new HRFWeb.Models.ReportAttributeModel()
{
AttributeGroupID = RA.AttributeGroupID,
AttributeID = RA.AttributeID,
ParentID = RA.ParentID,
Name = RA.Name,
Alias = RA.Alias,
IsCalculated = RA.IsCalculated,
FilterTypeID = RA.FilterTypeID,
FilterType = FT.Name,
DataSourceID = RA.DataSourceID,
DBName = DS.DBName,
ServerName = DS.ServerName,
ServerIP = DS.ServerIP,
DataSourceTable = RA.DataSourceTable,
LogiDataType = RA.LogiDataType,
TemplateID = g.TemplateID
};
if (FilterTemplateId != -1) {
result2 = from r in result2
where r.TemplateID == FilterTemplateID
select r;
}
答案 1 :(得分:0)
var result2 = from RA in ent.ReportAttributes
join FT in ent.FilterTypes on RA.FilterTypeID equals FT.FilterTypeID
join DS in ent.DataSources on RA.DataSourceID equals DS.DataSourceID
where templateID == -1 || (RA.TemplateAttributes != null && RA.TemplateAttributes.Any(rt=> rt.TemplateID == templateID))
select new HRFWeb.Models.ReportAttributeModel()
{
AttributeGroupID = RA.AttributeGroupID,
AttributeID = RA.AttributeID,
ParentID = RA.ParentID,
Name = RA.Name,
Alias = RA.Alias,
IsCalculated = RA.IsCalculated,
FilterTypeID = RA.FilterTypeID,
FilterType = FT.Name,
DataSourceID = RA.DataSourceID,
DBName = DS.DBName,
ServerName = DS.ServerName,
ServerIP = DS.ServerIP,
DataSourceTable = RA.DataSourceTable,
LogiDataType = RA.LogiDataType
};
通过使用导航属性...第二次检查templateID!= -1似乎是多余的