Linq to entities - 2个键之间的第一个字符串

时间:2012-09-06 18:17:11

标签: c# linq entity-framework

我正在使用实体框架,并且遇到了缺乏对某些扩展的支持的问题。

我有2个密钥(char)fromKeytoKey,我希望构建一个Where语句来搜索Stores列表,并选择Store.Name的第一个字母位于fromKeytoKey之间。

string[0]不起作用,Substring不起作用 - 任何人都有任何想法如何绕过这个?

子串方法的代码:

public static IQueryable<Store> FindActiveByName()
{
    var r = new ReadRepo<Store>(Local.Items.Uow.Context);

    Tuple<string, string> range = Tuple.Create("0", "9");
    return r.Find().Where(s => range.Item1 <= s.Name.Substring(0, 1) &&
                               s.Name.Substring(0, 1) <= range.Item2);
}

给我一​​个错误:

  

运算符&lt; =无法应用于字符串

更新

Anwser由nemesV提供

    public static IQueryable<Store> FindActiveByName()
    {
        Tuple<char, char> range = Tuple.Create('R', 'S');

        var r = new ReadRepo<Store>(Local.Items.Uow.Context);

        var keys = Enumerable
            .Range(range.Item1, (int)range.Item2 - (int)range.Item1 + 1)
            .Select(k => ((char)k).ToString());

        return r.Find(s => keys.Contains(s.Name.Substring(0, 1)));
    }

3 个答案:

答案 0 :(得分:2)

我手边没有EF,所以也许这个也行不通,但你可以尝试以下解决方法:

首先生成一个包含from to个字母的字符串。然后,您可以使用Contains检查Name的第一个字符是否在生成的字母中:

public static IQueryable<Store> FindActiveByName()
{
    var r = new ReadRepo<Store>(Local.Items.Uow.Context);

    Tuple<char, char> range = Tuple.Create('0', '9');

    var letters = Enumerable
                     .Range(range.Item1, (int)range.Item2 - (int)range.Item1 + 1)
                     .Select(x => ((char)x).ToString()

    return r.Find().Where(s => letters.Contains(s.Name.Substring(0, 1)));
}

或者你有明显的工作解决方法:

  • 在SQL中编写查询(EF具有执行任意查询的API,并构建实体)
  • .ToArray()之前插入Where,这将强制进行查询评估,Name.Substring比较将在客户端进行。

答案 1 :(得分:0)

你可以尝试这样的事情:

string[] data = { "Alex", "Bob", "John", "Danny", "Roy" };
char fromKey = 'A', toKey = 'D';
var query = data.Where(d => (int)d.First() >= (int)fromKey && (int)d.First() <= (int)toKey);

查询包含Alex, Bob and Danny

这只是一个例子。您可以根据需要进行更改。希望这会有所帮助。

答案 2 :(得分:0)

您的代码实际存在的唯一问题是.NET string类没有重载<=>=运算符。因此,代码无法编译(它与Entity Framework无关)。您可以使用string.CompareTo方法代替运算符:

public static IQueryable<Store> FindActiveByName()
{
    var r = new ReadRepo<Store>(Local.Items.Uow.Context);

    Tuple<string, string> range = Tuple.Create("0", "9");
    return r.Find().Where(s => 
        range.Item1.CompareTo(s.Name.Substring(0, 1)) <= 0 &&
        s.Name.Substring(0, 1).CompareTo(range.Item2) <= 0);
}

这将编译并使用Entity Framework并创建此SQL:

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[Name] AS [Name], 
FROM [dbo].[Stores] AS [Extent1]
WHERE (@p__linq__0 <= (SUBSTRING([Extent1].[Name], 0 + 1, 1)))
  AND ((SUBSTRING([Extent1].[Name], 0 + 1, 1)) <= @p__linq__1)

执行查询时,两个SQL参数p__linq__0p__linq__1将设置为传入的值"0""9"