我想使用LINQ将我从SQL Server数据库返回的行数限制为主键(WordId)第一个字符在A到E范围内的行。这是我目前的方式使用此LINQ执行此操作:
var words = db.WordForm
.Where(wf => string.Compare(wf.WordId.Substring(0, 1), "A") >= 0 &&
string.Compare(wf.WordId.Substring(0, 1), "E") <= 0)
.ToListAsync();
有人能告诉我这是最好的方法吗?还是有另一种方式使用LINQ?
答案 0 :(得分:3)
您可以使用SqlFunctions.Ascii
,此函数返回字符表达式最左侧字符的 ASCII 代码值,因此您可以像这样使用它:
int asciiA = Encoding.ASCII.GetBytes("A")[0];
int asciiE = Encoding.ASCII.GetBytes("E")[0];
var words = db.WordForm.Where(wf => SqlFunctions.Ascii(wf.WordId.ToUpper()) >= asciiA &&
SqlFunctions.Ascii(wf.WordId.ToUpper()) <= asciiE).ToListAsync();
答案 1 :(得分:1)
刚刚使用HashSet<T>
测试了不同的方法,没有它。如果我们有&lt;使用List<T>.Contains()
方法的20k记录就足够了:
var db = new List<MyClass>()
{
new MyClass() { WordId = "gds134" }, new MyClass() { WordId = "ads134" },
new MyClass() { WordId = "Cds134" }, new MyClass() { WordId = "Hds134" },
new MyClass() { WordId = "eds134" }, new MyClass() { WordId = "eds135" },
};
var lettersList = new List<char>() { 'a', 'b', 'c', 'd', 'e', 'A', 'B', 'C', 'D', 'E' };
var result = db.Where(x => lettersList.Contains(x.WordId.First()));
foreach(var item in result) Console.WriteLine(item.WordId);
输出:
ads134
Cds134
eds134
eds135
P.S。 另一个例子(包括简单的性能诊断):
答案 2 :(得分:1)
有人能告诉我这是最好的方法吗?或者在那里 使用LINQ的另一种方式?
有人肯定可以告诉你。但这将是基于有限信息的意见。你所拥有的将会发挥作用并发挥作用。你在用EF吗? LINQ是否转换为SQL查询?如果是这种情况,您肯定希望调试并查看正在生成的SQL。
如何调试SQL:
private EntitiesContext _context;
private EntitiesContext EntitiesContext
{
get
{
if (_context == null)
{
_context = new EntitiesContext();
_context.Database.Log = s => System.Diagnostics.Debug.WriteLine(s); //For debugging the SQL made by EF
}
return _context;
}
set { _context = value; }
}
如果您正在使用已创建的列表,则可以考虑使用regex。如果应用于EF上下文,我怀疑这将转化得非常糟糕。
答案 3 :(得分:0)
在代码中没有一种方法可以使用“A thru E”,您需要创建一个列表或字符串数组来表示您要检查的起始字母。
请看下面的示例解决方案:
我在代码中创建了WordForm对象;很明显,你的数据库来自你的数据库,你可以随心所欲地做到这一点。
.StartsWith("whatever")
Linq扩展方法是一个很好的比较,而不是使用.Substring(0,7) == "whatever"
。
public static void Main()
{
var words = new List<WordForm>();
words.Add(new WordForm { WordId = "Apple" });
words.Add(new WordForm { WordId = "Banana" });
words.Add(new WordForm { WordId = "Cake" });
words.Add(new WordForm { WordId = "Date" });
words.Add(new WordForm { WordId = "Egg" });
var filterChars = new string[] { "C", "D" };
var filtered = GetStartingWith(filterChars, words);
foreach (var item in filtered)
{
Console.WriteLine(item.WordId);
}
}
public static List<WordForm> GetStartingWith(string[] startingLetters, List<WordForm> collection)
{
var returnList = new List<WordForm>();
foreach (var wordForm in collection)
{
foreach (var startingLetter in startingLetters)
{
if (wordForm.WordId.StartsWith(startingLetter))
{
returnList.Add(wordForm);
}
}
}
return returnList;
}
public class WordForm
{
public string WordId { get; set; }
//... Plus all your other properties on WordForm...
}
这会让我回头
控制台中的“蛋糕”和“日期”。
以上内容:
给方法一个字母列表进行检查:在这种情况下A,B,C,D,E;以及要检入的列表(您的List<WordForm>
集合)
然后循环遍历WordForm对象并检查它是否以您给出的任何startingLetters开头。
如果匹配起始字母,例如"Cake".StartsWith("C")
(Cake以“C”开头),然后将其添加到列表中,然后将其与过滤后的对象一起返回。