Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何让我的LINQ查询生成我期望的SQL语句?_C#_Asp.net_Sql Server_Entity Framework_Where Clause - Fatal编程技术网

C# 如何让我的LINQ查询生成我期望的SQL语句?

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

我有一个简单的网页表单,其中有3个文本框和一个带有搜索按钮的下拉列表

这是我根据从4个控件中选择的输入筛选EF4.0上下文的代码:

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,
                        });