3

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

我有 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);
}

给我一个错误:

运算符 <= 不能应用于字符串

更新

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)));
    }
4

3 回答 3

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()之前插入一个,比较将在客户端完成。WhereName.Substring
于 2012-09-06T18:51:37.843 回答
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

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

于 2012-09-06T18:31:01.350 回答
0

您的代码实际存在的唯一问题是 .NETstring类没有重载<=>=运算符。因此,代码无法编译(它与实体框架无关)。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__0以及执行查询的时间。p__linq__1"0""9"

于 2012-09-06T22:08:23.527 回答