我有一个简单的网络表单,其中我有3个texboxes和一个带搜索按钮的下拉列表。
这是我根据4个控件中选择的输入过滤EF(4.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查询
TranslationEntity efSchema = new TranslationEntity();
gvTransValues.DataSource = (from defaultValue in efSchema.TRANS_VALUES
.Include("TRANS_CATEGORY")
where (
mFormId == "" ? 1 == 1 : defaultValue.FormId.Contains(mFormId)
&& mControlId == "" ? 1 == 1 : defaultValue.ControlId.Contains(mControlId)
&& mTransCategoryId == -1 ? 1 == 1 : defaultValue.TransCategoryId == mTransCategoryId
&& mDefaultTransValue == "" ? 1 == 1 : defaultValue.DefaultTranValue.Contains(mDefaultTransValue)
)
select new
{
TranValueId = defaultValue.TranValueId,
FormId = defaultValue.FormId,
ControlId = defaultValue.ControlId,
TransCategoryId = defaultValue.TransCategoryId,
CategoryName = defaultValue.TRANS_CATEGORY.CategoryName,
DefaultTranValue = defaultValue.DefaultTranValue,
});
gvTransValues.DataBind();
生成的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服务器方面做到最优的是让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
答案 0 :(得分:0)
尝试这样写:
(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 == ""))
答案 1 :(得分:0)
如果您以小步骤构建查询,这将会更加简单。
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,
});
(我认为它应该像这样工作但你可能必须指定query
的初始类型为IQueryable<YOURTYPE>
)