C# 如何让我的LINQ查询生成我期望的SQL语句?
我有一个简单的网页表单,其中有3个文本框和一个带有搜索按钮的下拉列表 这是我根据从4个控件中选择的输入筛选EF4.0上下文的代码:C# 如何让我的LINQ查询生成我期望的SQL语句?,c#,asp.net,sql-server,entity-framework,where-clause,C#,Asp.net,Sql Server,Entity Framework,Where Clause,我有一个简单的网页表单,其中有3个文本框和一个带有搜索按钮的下拉列表 这是我根据从4个控件中选择的输入筛选EF4.0上下文的代码: string mFormId = ddlTransValueSearchFormId.SelectedItem.Text.ToString().Trim(); string mControlId = ddlTransValueSearchControlId.SelectedItem.Text.ToString().Trim(); int mTransCategory
string mFormId = ddlTransValueSearchFormId.SelectedItem.Text.ToString().Trim();
string mControlId = ddlTransValueSearchControlId.SelectedItem.Text.ToString().Trim();
int mTransCategoryId;
try
{
mTransCategoryId = Int32.Parse(ddlTransValueSearchCategoryId.SelectedItem.Value.ToString());
}
catch(Exception ex)
{
throw ex;
}
string mDefaultTransValue = tbTransValueSearchDefaultValue.Text.ToString().Trim();
我的LINQ查询
生成的SQL语句
使用探查器,这是生成的SQL查询:
declare @p__linq__0 nvarchar(4000),@p__linq__1 nvarchar(4000),@p__linq__2 nvarchar(4000),@p__linq__3 nvarchar(4000),@p__linq__4 int,@p__linq__5 int,@p__linq__6 nvarchar(4000),@p__linq__7 nvarchar(4000)
SELECT @p__linq__0=N'',@p__linq__1=N'%%',@p__linq__2=N'',@p__linq__3=N'%%',@p__linq__4=1,@p__linq__5=1,@p__linq__6=N'cat',@p__linq__7=N'%cat%'
SELECT
[Extent1].[TRAN_VALUE_ID] AS [TRAN_VALUE_ID],
[Extent1].[FORM_ID] AS [FORM_ID],
[Extent1].[CONTROL_ID] AS [CONTROL_ID],
[Extent1].[TRANS_CATEGORY_ID] AS [TRANS_CATEGORY_ID],
[Extent2].[CATEGORY_NAME] AS [CATEGORY_NAME],
[Extent1].[DEFAULT_TRAN_VALUE] AS [DEFAULT_TRAN_VALUE]
FROM [dbo].[TRANS_VALUES] AS [Extent1]
LEFT OUTER JOIN [dbo].[TRANS_CATEGORY] AS [Extent2] ON [Extent1].[TRANS_CATEGORY_ID] = [Extent2].[TRANS_CATEGORY_ID]
WHERE
(CASE
WHEN (N'' = @p__linq__0) THEN cast(1 as bit)
WHEN (([Extent1].[FORM_ID] LIKE @p__linq__1 ESCAPE N'~') AND (N'' = @p__linq__2)) THEN cast(1 as bit)
WHEN (([Extent1].[CONTROL_ID] LIKE @p__linq__3 ESCAPE N'~') AND (-1 = @p__linq__4)) THEN cast(1 as bit)
WHEN (([Extent1].[TRANS_CATEGORY_ID] = @p__linq__5) AND (N'' = @p__linq__6)) THEN cast(1 as bit)
WHEN ([Extent1].[DEFAULT_TRAN_VALUE] LIKE @p__linq__7 ESCAPE N'~') THEN cast(1 as bit)
WHEN ( NOT ([Extent1].[DEFAULT_TRAN_VALUE] LIKE @p__linq__7 ESCAPE N'~')) THEN cast(0 as bit)
END) = 1
这不是我想要的。无论参数值如何,EF生成脚本的方式都是从数据库返回所有行
这里出了什么问题
我想要的SQL语句
实际上,在SQL Server方面,我需要和考虑的是优化EF来生成这种查询。
SELECT
[Extent1].[TRAN_VALUE_ID] AS [TRAN_VALUE_ID],
[Extent1].[FORM_ID] AS [FORM_ID],
[Extent1].[CONTROL_ID] AS [CONTROL_ID],
[Extent1].[TRANS_CATEGORY_ID] AS [TRANS_CATEGORY_ID],
[Extent2].[CATEGORY_NAME] AS [CATEGORY_NAME],
[Extent1].[DEFAULT_TRAN_VALUE] AS [DEFAULT_TRAN_VALUE]
FROM [dbo].[TRANS_VALUES] AS [Extent1]
LEFT OUTER JOIN [dbo].[TRANS_CATEGORY] AS [Extent2] ON [Extent1].[TRANS_CATEGORY_ID] = [Extent2].[TRANS_CATEGORY_ID]
WHERE
ISNULL([Extent1].[FORM_ID],N'') LIKE '%' + COALESCE(@p__linq__0,[Extent1].[FORM_ID],N'') + '%'
AND ISNULL([Extent1].[CONTROL_ID],N'') LIKE '%' + COALESCE(@p__linq__1,[Extent1].[CONTROL_ID],N'') + '%'
AND ISNULL([Extent1].[TRANS_CATEGORY_ID],-1) = COALESCE(@p__linq__2,[Extent1].[TRANS_CATEGORY_ID],-1)
AND ISNULL([Extent1].[DEFAULT_TRAN_VALUE],N'') LIKE '%' + COALESCE(@p__linq__3,[Extent1].[DEFAULT_TRAN_VALUE],N'') + '%'
go
试着这样写:
(from defaultValue in efSchema.TRANS_VALUES
.Include("TRANS_CATEGORY")
where (defaultValue.FormId.Contains(mFormId) || mFormId == "")
&& (defaultValue.ControlId.Contains(mControlId) || mControlId == "")
&& (defaultValue.TransCategoryId.Contains(mTransCategoryId) || mTransCategoryId == "")
&& (defaultValue.DefaultTranValue.Contains(mDefaultTransValue) || mDefaultTransValue == ""))
如果您以小步骤构造查询,这将简单得多
var query = efSchema.TRANS_VALUES.Include("TRANS_CATEGORY");
if(!string.IsNullOrEmpty(mFormId))
{
query = query.Where(defaultValue => defaultValue.FormId.Contains(mFormId));
}
if(!string.IsNullOrEmpty(mControlId))
{
query = query.Where(defaultValue => defaultValue.ControlId.Contains(mControlId));
}
if(mTransCategoryId != -1)
{
query = query.Where(defaultValue => defaultValue.TransCategoryId == mTransCategoryId);
}
if(!string.IsNullOrEmpty(mDefaultTransValue))
{
query = query.Where(defaultValue => defaultValue.DefaultTransValue.Contains(mDefaultTransValue));
}
gvTransValues.DataSource = query.Select(defaultValue => new
{
TranValueId = defaultValue.TranValueId,
FormId = defaultValue.FormId,
ControlId = defaultValue.ControlId,
TransCategoryId = defaultValue.TransCategoryId,
CategoryName = defaultValue.TRANS_CATEGORY.CategoryName,
DefaultTranValue = defaultValue.DefaultTranValue,
});
我认为它应该是这样工作的,但是您可能必须将查询的初始类型指定给IQueryable,这看起来是个问题。尝试在条件周围加上括号。如果EF不能自动生成所需的代码,我建议您将其包装在存储过程中。@Johnbot-您是对的!我在where子句周围添加了偏执,现在它可以正常工作了。谢谢你,伙计!这样做了,现在就可以了!谢谢虽然你的情况与我需要的不一样,但我需要考虑将此标记为已回答,以便你的问题从未回答的队列中删除。谢谢,祝你好运!
var query = efSchema.TRANS_VALUES.Include("TRANS_CATEGORY");
if(!string.IsNullOrEmpty(mFormId))
{
query = query.Where(defaultValue => defaultValue.FormId.Contains(mFormId));
}
if(!string.IsNullOrEmpty(mControlId))
{
query = query.Where(defaultValue => defaultValue.ControlId.Contains(mControlId));
}
if(mTransCategoryId != -1)
{
query = query.Where(defaultValue => defaultValue.TransCategoryId == mTransCategoryId);
}
if(!string.IsNullOrEmpty(mDefaultTransValue))
{
query = query.Where(defaultValue => defaultValue.DefaultTransValue.Contains(mDefaultTransValue));
}
gvTransValues.DataSource = query.Select(defaultValue => new
{
TranValueId = defaultValue.TranValueId,
FormId = defaultValue.FormId,
ControlId = defaultValue.ControlId,
TransCategoryId = defaultValue.TransCategoryId,
CategoryName = defaultValue.TRANS_CATEGORY.CategoryName,
DefaultTranValue = defaultValue.DefaultTranValue,
});