これにはいくつかのレベルがあります。 where ((e.OwnerID == id) || (id == 0))
のようなwhere
句を使用して生成されたSQLに埋め込みます。または、別の方法で、異なるwhere
句の亜種のLINQ式全体を4つの別々のコピーにすることができます。私は個人的にはミッドウェイのアプローチをお勧めします:共通部分を繰り返すことなく、フィルタに基づいて異なるIQueryable
値を構築するために、コードの別の枝を使用します。
public dynamic GetData(int id, string title)
{
var baseQuery =
from ep in dbContext.tbl_EntryPoint
join e in dbContext.tbl_Entry on ep.EID equals e.EID
join t in dbContext.tbl_Title on e.TID equals t.TID
select new { e, t };
var filtered = baseQuery; // Implicitly type filtered to match the anonymous type in baseQuery
if (id > 0)
{
if (!string.IsNullOrWhiteSpace(title))
filtered = baseQuery.Where(ep => (ep.e.OwnerID == id) || (ep.t.title == title));
else
filtered = baseQuery.Where(ep => ep.e.OwnerID == id);
}
else
{
if (!string.IsNullOrWhiteSpace(title))
filtered = baseQuery.Where(ep => ep.t.title == title);
else
filtered = baseQuery;
}
var entryPoint = filtered.Select(ep =>
new
{
UID = ep.e.OwnerID,
TID = ep.e.TID,
Title = ep.t.Title,
EID = e.EID
}).Take(10);
...
}
Entity Frameworkのは、匿名型で、知っているのに十分スマートですbaseQuery
で構成され、ep.e
は、tbl_Entry
結合表を示し、ep.t
は、tbl_Title
結合表を参照しています。ここでは上記のコードから生成されたSQLのサンプルです:
SELECT
[Limit1].[EID] AS [EID],
[Limit1].[OwnerID] AS [OwnerID],
[Limit1].[TID] AS [TID],
[Limit1].[Title] AS [Title],
[Limit1].[EID1] AS [EID1]
FROM (SELECT TOP (10)
[Extent1].[EID] AS [EID],
[Extent2].[EID] AS [EID1],
[Extent2].[OwnerID] AS [OwnerID],
[Extent2].[TID] AS [TID],
[Extent3].[Title] AS [Title]
FROM [dbo].[tbl_EntryPoint] AS [Extent1]
INNER JOIN [dbo].[tbl_Entry] AS [Extent2] ON [Extent1].[EID] = [Extent2].[EID]
INNER JOIN [dbo].[tbl_Title] AS [Extent3] ON [Extent2].[TID] = [Extent3].[TID]
WHERE [Extent2].[OwnerID] = @p__linq__0 OR [Extent3].[Title] = @p__linq__1
) AS [Limit1]
(これは両方とも非ゼロid
で生成され、空でないtitle
、ひいてはで.Where
を呼び出して、非常に最初のif
ケースを下って行きましたid
とtitle
の両方をテストする式。
'(id!= 0 && e.OwnerID == id)|| t.title == title' –