2013-01-21 75 views
0

我使用下面的LINQ查詢使用XML文件來工作..使用如果LINQ查詢else語句

XElement rootElement = XElement.Load(@"test.xml"); 
int StyCode; 
var lv1s = from lv1 in rootElement.Descendants("Class") 
where lv1.Attribute("Code").Value.Equals("002") 
select new 
{ 
Children = from ltd in lv1.Descendants("Subject") 
where ltd.Attribute("Course").Value.Equals("Math") 
select new 
{ 

****//In This below section need result on condition based... **** 
if(StyCode=0) 
{ 
Children1 = ltd.Attribute("AllTeachers").Value.Equals("Y") ? true : false 
} 
else 
{ 
Children2 = ltd.Attribute("SpeciaGuest").Value.Equals("Y") ? true : ltd.Elements("Topic").Attributes("Code").Where(x => x.Value.Equals("1")).FirstOrDefault() != null ? true : false 
} 
} 
}; 

下面是我的XML結構..

<?xml version="1.0" encoding="utf-8" ?> 
<Document> 
    <Class Code="001"> 
    <Subject Course="Math" AllTeachers='N' SpeciaGuest='N'></Subject> 
    <Subject Course="Engish" AllTeachers='Y' SpeciaGuest='Y'></Subject> 
    <Subject Course="History" AllTeachers='Y' SpeciaGuest='Y'></Subject> 
    </Class> 
    <Class Code="002"> 
    <Subject Course="Math" AllTeachers='Y' SpeciaGuest='N'> 
     <Topic Code="1">LAW1</Topic> 
     <Topic Code="2"> 
     LAW2 
     </Topic> 
     <Topic Code="3"> 
     LAW3</Topic> 
     </Subject> 
    <Subject Course="Engish" AllTeachers='Y' SpeciaGuest='Y'></Subject> 
    <Subject Course="History" AllTeachers='Y' SpeciaGuest='Y'></Subject> 
    </Class> 
</Document> 

請讓我知道,怎麼樣我可以使用條件來選擇多個選擇結果。還讓我知道在這個linq查詢中使用resharper會好嗎?

+3

兩者不具有相同的類型。一個是「字符串」,另一個是「布爾」。他們需要有相同的類型才能工作。他們也應該真實地擁有相同的名字,否則你永遠無法使用他們中的任何一個。 – Servy

+0

@Servy:修改代碼.. – intelliWork

+0

你只解決了我提到的兩個問題之一。還要注意,你的if不是基於該項目,而是基於查詢範圍之外的值,所以只需在查詢之外拉出if即可。 – Servy

回答

1

因爲if(StyCode=0)不是基於序列中的當前項,你可以將if拉到查詢外部:

另請注意,因爲Select子句都選擇單個項目,所以不需要匿名類型,只需選擇該項目即可。這導致在此:

XElement rootElement = XElement.Load(@"test.xml"); 
int StyCode = 0; 
IEnumerable<IEnumerable<bool>> lv1s; 
if (StyCode == 0) 
{ 
    lv1s = from lv1 in rootElement.Descendants("Class") 
      where lv1.Attribute("Code").Value.Equals("002") 
      select (from ltd in lv1.Descendants("Subject") 
        where ltd.Attribute("Course").Value.Equals("Math") 
        select ltd.Attribute("AllTeachers").Value.Equals("Y") ? true : false); 
} 
else 
{ 
    lv1s = from lv1 in rootElement.Descendants("Class") 
      where lv1.Attribute("Code").Value.Equals("002") 
      select (from ltd in lv1.Descendants("Subject") 
        where ltd.Attribute("Course").Value.Equals("Math") 
        select ltd.Attribute("SpeciaGuest").Value.Equals("Y") ? true : ltd.Elements("Topic").Attributes("Code").Where(x => x.Value.Equals("1")).FirstOrDefault() != null ? true : false); 
} 

因此,這是簡單的,和漂亮,但有很多的重複代碼,這也不是沒有很好的。另一條向下的道路是創建一個方法,它需要代表ltdXElement以及整數StyCode,並返回指示適當值的布爾值。這是一個很簡單的方法來寫:

private static bool GetChildFromSubject(int styCode, XElement subject) 
{ 
    if (styCode == 0) 
     return subject.Attribute("AllTeachers").Value.Equals("Y"); 
    else 
    { 
     return subject.Attribute("SpeciaGuest").Value.Equals("Y") || 
       subject.Elements("Topic").Attributes("Code") 
       .Any(x => x.Value.Equals("1")); 
    } 
} 

現在,我們只需要一個查詢:

XElement rootElement = XElement.Load(@"test.xml"); 
int StyCode = 0; 
var lv1s = from lv1 in rootElement.Descendants("Class") 
      where lv1.Attribute("Code").Value.Equals("002") 
      select (from ltd in lv1.Descendants("Subject") 
        where ltd.Attribute("Course").Value.Equals("Math") 
        select GetChildFromSubject(StyCode, ltd)); 

好多了。

+0

謝謝Servy,這是更好的代碼,如果你有任何更好的linq參考或編碼指南請讓我知道。 – intelliWork

1

您不能創建具有不同屬性的匿名對象。那麼序列類型是什麼?你可以(通過三元運營商?:

XDocument xdoc = XDocument.Load(@"test.xml"); 

var lv1s = from c in xdoc.Descendants("Class") 
      where (string)c.Attribute("Code") == "002" 
      select new { 
       Children = (StyCode == 0) ? 
          ((string)c.Attribute("AllTeachers") == "Y") : 
          ((string)c.Attribute("SpeciaGuest") == "Y") || 
          c.Elements("Topic")         . 
          .Any(t => (string)t.Attribute("Code") == "1")) 
      }; 

BTW你正在返回與布爾Children屬性的對象的列表分配到相同屬性的值不同。我相信你需要更多的數據。

1
bool flag = boolexpression ? true : false; 

相同

bool flag = boolexpression; 

所以,請停止使用三元到不必要的代碼複雜化。


你可以寫你的SELECT子句:

select new 
{ 
    Children1 = (StyCode==0) ? ltd.Attribute("AllTeachers").Value.Equals("Y") : false, 
    Children2 = (StyCode==0) ? false : 
    ltd.Attribute("SpeciaGuest").Value.Equals("Y") 
    || ltd.Elements("Topic").Attributes("Code").Where(x => x.Value.Equals("1")).FirstOrDefault() != null 
} 

也許有人會說,重複條件不好的形式。如果你是在營地,我建議使用這個代替:

select (StyCode == 0) ? objectContructor1(ltd) : objectConstructor2(ltd) 
+0

但我一次想返回一個結果Children1或Children2根據我的if和else條件 – intelliWork

1

您需要使用條件運算符:

Children1 = StyCode == 0 ? 
    ltd.Attribute("AllTeachers").Value == "Y" 
: 
    (ltd.Attribute("SpeciaGuest").Value == "Y" 
|| ltd.Elements("Topic").Attributes("Code").Select(a => a.Value).Contains("1") 
    )