string.equals函数无法正常工作c#

时间:2016-02-03 16:08:16

标签: c# .net string linq

我陷入了一个非常简单的问题,我只是在LINQ查询的where子句中比较c#中的两个字符串。但它没有处理区分大小写的问题。我累了。 这是我的代码

bin

我的cs代码看起来像

public class User
{
    [Key()]
    public long ID { get; set; }

    [Required]
    public string Fname { get; set; }

    [Required]
    [Display(Name = "Last Name")]
    public string Lname { get; set; }

    [DataType(DataType.PhoneNumber)]
    public string Ph_Num { get; set; }

    public string CNIC { get; set; }

    [Required]
    [Display(Name="Username")]

    public string Username { get; set; }
    [Required]

    public string Password { get; set; }

    public string Designation { get; set; }

    public DateTime CreatedDate { get; set; }
}

3 个答案:

答案 0 :(得分:1)

在比较LINQ lamda表达式中的2个字符串值时,默认情况下会进行区分大小写的比较。但是如果你不希望有这种行为,你可以使用Equals方法的不同重载,它将比较类型枚举作为第二个参数,你可以传递你想要的比较类型(区分大小写或Case不敏感)。对于不区分大小写的比较,您可以传递StringComparison.CurrentCultureIgnoreCase

var resultsWithCaseIgnored = someEntityList.Where(i => i.Name
                      .Equals("scott",StringComparison.CurrentCultureIgnoreCase)).ToList();

但是当您执行LINQ to SQL语句,它将生成一个SQL语句并执行它时,生成的SQL对于这两个重载都是相同的。

SQL语句中where子句的区分大小写取决于db服务器/ db /特定列上的排序规则设置。

您可以通过执行类似

的sql语句来验证当前设置
SELECT CONVERT (varchar, SERVERPROPERTY('collation'));

当我在我的sql server中运行它时,得到的结果是 "SQL_Latin1_General_CP1_CI_AS" CI部分表示,它不区分大小写。这意味着当我执行where UserName='scott'where UserName='SCOTT'时,两者都会给我相同的结果。

如果要进行区分大小写检查,可以通过多种方法将排序规则更新为区分大小写的方法。但更新数据库并不总是安全的事情(考虑其含义

您可以做的是,查询您的数据库表,将结果发送到您的C#对象,然后执行where子句( ,区分大小写 )。

var users= db.Users.Where(i => i.Username.Equals(username)).ToList();

// do a case sensitive check on users
var user = users.FirstOrDefault(s=>s.Username.Equals(username));
if(user!=null)
{
  // user has the User object
}
else
{ 
  // no user matching our CASE SENSITIVE UserName check.
}

答案 1 :(得分:0)

问题不在于C#......它在你的SGBD中的问题。例如,在SQL Server中检查您拥有的文化设置。如果它是包含“CI”的东西,则所有内容都将以不敏感的方式进行比较。那是因为你看到它只是一个表达式树,它被翻译成纯SQL并在你的SGBD上执行。更多详情:https://msdn.microsoft.com/en-us/library/ms180175.aspx

注意:您可以通过在LINQ查询中调用“ToUpper”或“ToLower”来欺骗它:

public ActionResult Index(string username, string password)
    {
        if (username != "" && password != "")
        {
            //checking is user already exists

            //Here problem arise...
            userName = userName.ToUpperInvariant ();
            var query = db.Users.Where(i => i.Username.ToUpper ().Equals(username)).ToList();
            User res = null;
            if(query.Count == 1)
            {
                res = query.First();
            }
            if (res != null)
            {
                //My remaining code
            }
        }
        return View("Index");
    }

这将在SQL中转换为类似UPPER(UserName)='BLABLA'

的内容

答案 2 :(得分:0)

问题是您的Linq查询正在转换为SQL,因此数据库中的设置将确定比较是区分大小写还是不区分大小写。既然你想要区分大小写,但是不区分大小写,我建议使用AsEnumerable

在Linq-to-Objects中做第二个过滤器
var query = db.Users.Where(i => i.Username == username)
                    .AsEnumerable()
                    .Where(i => i.Username == username)
                    .ToList();

基本上这将确保第二个Where将在您的代码中执行而不是转换为SQL。因为C#中的字符串比较区分大小写,所以你应该得到你想要的。请注意,您仍然希望保留第一个Where,以确保您不会从数据库中返回表格的所有行,这可能代价高昂。您只是以不区分大小写的方式返回匹配的行,其中包括任何区分大小写的匹配。