将函数或扩展方法与linq组合以匹配别名的问题

时间:2013-11-26 12:07:21

标签: c# asp.net-mvc-3 linq-to-sql

在数据库中,我从几个别名中获取数据用于一个ID(捕获所有ID),并且对于需要与此ID进行比较的值也会发生相同的情况。 Linq不允许我使用扩展名或函数来选择记录,或者我在这里做错了。

假设null,“_”,“”和“Default”是Catch All ID的可能值,其中任何其他值都应被视为单独的值。

我正在寻找一种方法来生成一个linq选择,它以干净和可维护的方式匹配别名。

似乎有用的是:

using (DataContext context = new DataContext())
{
   var q = (from c in context.BasketContents
            where
            (c.ID+" ").Replace("Default", "").Replace("_", "") 
             == 
            (Value+" ").Replace("Default", "").Replace("_", "")
            select c);
}

或者这也有效:

where ((c.ID==null |c.ID=="Default" | c.ID=="_" | c.ID=="") & 
       (Value==null |Value=="Default" | Value=="_" | Value=="")) |
       (c.ID==Value))

哪个更糟糕:)

由于这种比较需要在相当多的查询中进行,我想使用扩展或函数,所以我尝试组合以下内容:

    private bool IsSameID(string a1, string a2)
    {
        return ((a1 == null | a1 == "Default" | a1 == "_" | a1 == "")
        && (a2 == null | a2 == "Default" | a2 == "" | a2 == "_"))
        | (a1 == a2) ? true : false;
    }

查询:

using (DataContext context = new DataContext())
{
   var q = (from c in context.BasketContents
            where
            IsSameID(c.ID,Value)
            select c);
}

这会引发以下异常:Boolean'IsSameID(System.String,System.String)'没有支持的SQL转换

我还写了一个扩展方法来处理替换:

public static string DeAlias(this string a)
{
   return (a == null | a == "Default" | a == "_" | a == "") ? "" : a;
}

所以我可以比较ID.DeAlias() == Value.DeAlias(),但这基本上有同样的问题。

那我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

LINQ to SQL无法将您的自定义方法转换为SQL。您应该在客户端过滤您的购物篮内容:

from c in context.BasketContents.AsEnumerable()
where IsSameID(c.ID,Value)
select c

或者不要使用自定义方法

from c in context.BasketContents
where (c.ID == null || c.ID == "Default" || c.ID == "_" || c.ID == "") &&
       c.ID == Value
select c

正如我在评论中指出的那样,如果要从查询中提取复杂的过滤,还可以创建返回类型Expression<Func<BasketContents,bool>>的表达式的方法:

private Expression<Func<BasketContents,bool>> IsSameID(string value)
{
    return (Expression<Func<BasketContents,bool>>)(c => 
         ((c.ID == null || c.ID == "Default" || c.ID == "_" || c.ID == "") &&
          c.ID == value);              
}

在这种情况下,查询将如下所示:

context.BasketContents.Where(IsSameID("your value"));