2013-01-21 74 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") 
    )