2012-05-01 40 views
1

LINQ中是否有方法來確定哪些WHERE子句受到影響?我有一個叫做Company的對象,它可以有多個BillTo對象,每個BillTo對象可以有多個Generator對象。如何確定LINQ聲明中的哪些WHERE子句爲真

Company 
| 
+-- BillTo1 - named First 
| | 
| |-- Generator1 - named Alpha 
| | 
| +-- Generator2 - named Beta 
| 
+-- BillTo2 - named Second 
    | 
    +-- Generator3 - name Gamma 

這裏是LINQ的語句(去掉了多餘的東西其他地方語句):

bool HaveCompany = !string.IsNullOrWhiteSpace(Company); 
var AllData = (from co in db.Companies 
      join bt in db.Billtoes on co.ID equals bt.CompanyID into bts 
      from b in bts.DefaultIfEmpty() 
      join gn in db.Generators on b.ID equals gn.BillToID into gns 
      from g in gns.DefaultIfEmpty() 
      where co.Active == true 
      && (
       co.Name.Contains(HaveCompany ? Company : co.Name) || 
       b.Name.Contains(HaveCompany ? Company : b.Name) || 
       g.Name.Contains(HaveCompany ? Company : g.Name) 
      ) 
      select new { 
       CompanyID = co.ID, 
       BillTo = b, 
       Generator = g, 
       Name = co.Name, 
      }).ToList(); 

的問題是,它正確耳目一新。如果我在BillTo上找到「名稱」匹配項,我不需要做「Generator = g」,反之亦然,如果我在發生器上找到它,我不需要做「BillTo = b」。

因此,如果有一種方法可以知道哪個WHERE子句被命中,那麼我會將相應的b或g添加到結果中。我知道我可以通過AFTER重申我得到的結果,並重新檢查我實際上作爲WHERE子句發送的7個字段中的每一個,但這看起來像是額外的代碼。也許我的LINQ的調整是爲了?是否有價值可以通過反思或somethng提取出來,以找出遭遇的是什麼?

+3

只是不這樣做與LINQ? – SimpleVar

+0

我只能看到1 Where子句。 –

+0

@YoryeNathan我使用EF和LINQ是合乎邏輯的選擇。 – Grandizer

回答

3

你必須決定 - 你想要三個選擇分支(其實它將是兩個嵌套的?:陳述我應該考慮)?或者你想選擇一個擁有所有潛在成員的對象嗎?就個人而言,以避免在您的select語句中使用的具體類型,或使用dynamic我只是想擴展您的匿名類型:

您可以使用letContains檢查只是一次,然後同時使用在你的where條款的而在匿名類型成員的分配:

/* .... */ 
let coContains = co.Name.Contains(HaveCompany ? Company : co.Name) 
let bContains = b.Name.Contains(HaveCompany ? Company : b.Name) 
let gContains = g.Name.Contains(HaveCompany ? Company : g.Name) 
where co.Active == true 
&& (coContains || bContains || gContains) 
select new { 
    /* sticking the booleans on there as well - might not want to do that */ 
    CoContains = coContains, 
    BContains = bContains, 
    GContains = gContains, 
    /* other properties as per your code example */ 
    CompanyID = co.ID, 
    BillTo = !gContains && bContains ? b : (BillTo)null, 
    Generator = gContains && !bContains ? g : (Generator)null, 
    Name = co.Name 
}).ToList(); 

所以你仍然返回相同的數據(如評論說,你可能不會真的想那些多餘的 布爾,我只有把它們放在那裏,因爲它可能會簡化你以後運行的任何控制流邏輯),但你只是分配了如果布爾符合(我認爲是)你的標準。 BillToGenerator屬性將是null(我在這裏假設類型名稱),如果他們不應該被讀取。

+1

OP希望*投影*取決於不同'where'子句的結果 - 'let'子句在這種情況下不起作用 – BrokenGlass

+0

@BrokenGlass - 它可能;但我認爲你的觀點:)我不完全確定它很清楚需要什麼,但是我會看看我能不能拿出一些東西 –

+0

你可以在投影中使用布爾變量。爲什麼不可能,安德拉斯佐爾坦? – usr

0

如果您正在辨別符合哪個條件,則可能會對數據進行分區而不是對其進行過濾。分區是GroupBy的工作。然後,您可以基於密鑰進行條件組投影。

.GroupBy(x => x.co.Name.Contains(HaveCompany ? Company : co.Name) ? 1 : 
    x.b.Name.Contains(HaveCompany ? Company : b.Name) ? 2 : 
    x.gen.Name.Contains(HaveCompany ? Company : gen.Name) ? 3 : 
    0 
) 
.SelectMany(g => 
g.Key == 1 ? g.Select(x => new { 
    CompanyID = x.co.ID, 
    BillTo = x.b, 
    Generator = x.gen, 
    Name = co.Name 
} : 
g.Key == 2 ? g.Select(x => new { 
    CompanyID = co.ID, 
    BillTo = b, 
    Generator = (Generator) null, 
    Name = co.Name 
} : 
g.Key == 3 ? g.Select(x => new { 
    CompanyID = co.ID, 
    BillTo = (BillTo) null, 
    Generator = gen, 
    Name = co.Name 
} : 
g.Where(x => false) 
)