如果可用则使用appguid否则在LINQ中使用硬编码guid

时间:2013-06-11 21:16:54

标签: c# linq lambda active-directory

我怎样才能写下lambda表达式,以便它可以检查匹配的appguid,如果它找不到,那么它会查找硬编码的guid吗?

public static string ActiveDirectory(string xmlPath, string applicationGUID,string Element)
{
    XDocument dbConfig = XDocument.Load(xmlPath);

    return (dbConfig
                     .Descendants("Zone")
                     .Where(a =>
                     {
                         XElement ag = a.Element("ApplicationGUID");
                         return ag != null &&
                                (ag.Value == applicationGUID || ag.Value == "3773e594efga42688cd5113cf316d4d3");
                     })
                     .Select(
                         a =>
                         {
                             XElement cs = a.Element(Element);
                             return cs == null
                                        ? null
                                        : cs.Value;
                         })
                     .SingleOrDefault());
}

这就是我的xml的样子

<Zone>

        <ApplicationGUID>69b150127e7d43efa0e3e896b94953de</ApplicationGUID>
        <isActiveDirectory>true</isActiveDirectory>
        <ActiveDirectoryPath>LDAP://test.org</ActiveDirectoryPath>
        <DomainName>test1</DomainName>
    </Zone>
  <Zone>
           <ApplicationGUID>3773e594efga42688cd5113cf316d4d3</ApplicationGUID>
    <!--Default App guid-->
    <isActiveDirectory>true</isActiveDirectory>
    <ActiveDirectoryPath>LDAP://test.org</ActiveDirectoryPath>
    <DomainName>test2</DomainName>
  </Zone>
</Zones>

2 个答案:

答案 0 :(得分:0)

默认返回第二个查询,例如......

public static string ActiveDirectory(string xmlPath, string applicationGUID, string Element)
{
    XDocument dbConfig = XDocument.Load(xmlPath);

    var ret = (dbConfig
                     .Descendants("Zone")
                     .Where(a =>
                     {
                         XElement ag =
                             a.Element("ApplicationGUID");

                         return ag != null &&
                                (ag.Value == applicationGUID);
                     })
                     .SingleOrDefault());

    if(ret == null)
       ret = (dbConfig
                     .Descendants("Zone")
                     .Where(a =>
                     {
                         XElement ag =
                             a.Element("ApplicationGUID");

                         return ag != null &&
                                (ag.Value == "3773e594efga42688cd5113cf316d4d3");
                     })
                     .SingleOrDefault());

    if(ret != null)
    {
           XElement cs = ret.Element(Element);

           return cs == null ? null : cs.Value;
    }

    return null;
}

你可以用技巧来使它成为单个语句,但为什么要混淆语句。假设您的XML不是很长并且不会反复调用此函数,这可能不会成为您的瓶颈,同时使代码更容易阅读和理解。

但是,如果您真的只想要一个语句,那么您可以尝试使用OrderBy来设置优先级,例如:

public static string ActiveDirectory(string xmlPath, string applicationGUID,string Element)
{
XDocument dbConfig = XDocument.Load(xmlPath);

return (dbConfig
                 .Descendants("Zone")
                 .Where(a =>
                 {
                     XElement ag =
                         a.Element("ApplicationGUID");

                     return ag != null &&
                            (ag.Value == applicationGUID || ag.Value == "3773e594efga42688cd5113cf316d4d3");
                 })
                 .OrderBy(a => a.Element("ApplicationGUID").Value == "3773e594efga42688cd5113cf316d4d3" ? 1 : 0)
                 .Select(
                     a =>
                     {
                         XElement cs =
                             a.Element(Element);

                         return cs == null
                                    ? null
                                    : cs.Value;
                     })
                 .FirstOrDefault());
}

这个OrderBy给出了Guid不是静态优先级的排序优先级,然后使用FirstOrDefault获得最高优先级匹配,这是ag.Value == applicationGuid的情况。请注意,我不确定a.Element(...)不是第一个为空,因为它上方的Where将过滤掉它为空的任何位置。

答案 1 :(得分:0)

您在声明的最后选择了SingleOrDefault()。在您的示例数据中,您提供了两个与Where() Func的匹配项。如果存在单个匹配,则SingleOrDefault返回单个成员,如果没有匹配则返回返回类型的默认值,或者抛出异常。在你的情况下,两个匹配,因此是一个例外。

您尝试做的最简单的解决方案是运行两个查询。首先检查传递的ID是否匹配,如果没有,请查找与您的硬编码值的匹配。