C# 如何使用LINQ仅返回列的第一个字符在某个范围内的行?

C# 如何使用LINQ仅返回列的第一个字符在某个范围内的行?,c#,sql-server,linq,C#,Sql Server,Linq,我想使用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.Subst

我想使用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();
var words=db.WordForm
其中(wf=>string.Compare(wf.WordId.Substring(0,1),“A”)>=0&&

string.Compare(wf.WordId.Substring(0,1),“E”)您可以使用
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();
intascia=Encoding.ASCII.GetBytes(“A”)[0];
int ascie=Encoding.ASCII.GetBytes(“E”)[0];
var words=db.WordForm.Where(wf=>SqlFunctions.Ascii(wf.WordId.ToUpper())>=asciiA&&

SqlFunctions.Ascii(wf.WordId.ToUpper())在代码中没有“a到E”的方法,您需要创建一个字符串列表或数组来表示要检查的起始字母

请看以下示例解决方案:

我已经在代码中创建了WordForm对象;显然,您的对象来自您的DB,您可以使用它们做您需要的事情

.StartsWith(“whatever”)
Linq扩展方法是一个很好的比较,而不是使用
.Substring(0,7)=“whatever”

publicstaticvoidmain()
{
var words=新列表();
添加(新的WordForm{WordId=“Apple”});
添加(新的WordForm{WordId=“Banana”});
添加(新的WordForm{WordId=“Cake”});
添加(新的WordForm{WordId=“Date”});
添加(新的WordForm{WordId=“Egg”});
var filterChars=新字符串[]{“C”,“D”};
var filtered=GetStartingWith(filterChars,words);
foreach(过滤后的变量项)
{
Console.WriteLine(item.WordId);
}
}
公共静态列表GetStartingWith(字符串[]startingLetters,列表集合)
{
var returnList=新列表();
foreach(集合中的var wordForm)
{
foreach(var startingLetter在startingLetters中)
{
if(wordForm.WordId.StartsWith(startingLetter))
{
returnList.Add(wordForm);
}
}
}
退货清单;
}
公共类词形
{
公共字符串WordId{get;set;}
//…加上WordForm上的所有其他属性。。。
}
这是我的回报

控制台中的“蛋糕”和“日期”

上面的功能:

为方法提供一个要检查的字母列表:在本例中为a、B、C、D、E;以及要检查的列表(您的
列表
集合)

然后,它在WordForm对象中循环,并检查它是否以您给定的任何起始字母开头


如果它匹配一个起始字母,例如
“Cake”.StartsWith(“C”)
(Cake以“C”开头),则将其添加到一个列表中,然后在该列表中返回过滤对象。

刚刚测试了不同的方法,有
哈希集和没有它。如果我们有<20k条记录,则使用的
list.Contains()
方法应足够:

        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);
附言。 另一个示例(包括简单的性能诊断):

有人能告诉我这是做这件事的最好的方法吗 使用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; }
        }

如果您正在使用已经创建的列表,那么您可能会考虑使用A。如果应用到EF上下文,这将非常糟糕地翻译。

可能的副本是如何对<代码>“A”<代码> > <代码> > E的。
?WordForm中有多少行?使用计算列是否不值得考虑?@MaxSorin-我没有考虑使用小写。这是一个问题,我想我需要修改代码。谢谢you@JeroenHeier-表中大约有1000-2000行。你能解释一下计算列的意思吗?为什么比OP方式更好?@Sophia更新了rexter的链接,请检查新链接
ads134
Cds134
eds134
eds135
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; }
        }