LinqToSql和HashBytes

时间:2010-12-16 19:33:52

标签: .net linq-to-sql

我需要执行这个Sql命令(在管理工作室中可以正常工作):

select * from Users where Login = 'test' and PasswordHash = HashBytes('SHA1', 'test')

我写了这个c#linqtosql:

var user = db.ExecuteQuery<User>("select * from Users where Login = {0} and PasswordHash = HashBytes('SHA1', {1})", loginTextBox.Text.Trim(), passwordPasswordBox.Password).SingleOrDefault();

但它永远不会有效!!

任何人都可以帮助我吗?

谢谢!

这是DataContext的日志:

select * from Users where Login = @p0 and PasswordHash = HashBytes('SHA1', @p1)
-- @p0: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [test]
-- @p1: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [test]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1

3 个答案:

答案 0 :(得分:4)

我通过db.Log = Console.Out对其进行了分析,结果为:

-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1

select * from Users where Login = @p0 and PasswordHash = HashBytes('SHA1', @p1)
-- @p0: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [Admiral Trask]
-- @p1: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [Arutha]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1

看着这个,我想象问题是param是NVarChar而不是varchar - 所以取哈希(二进制运算)是不同的。如果哈希它为varchar,您可能应该在varchar之前将字符串转换为HASHBYTES

以下作品,例如:

var user = db.ExecuteQuery<User>(@"select * from Users where Login = {0}
        and PasswordHash = HashBytes('SHA1', CAST({1} as varchar(40)))", cn, pw)
        .SingleOrDefault();

更简单的说明是:

SELECT HASHBYTES('SHA1','12345'), HASHBYTES('SHA1',N'12345')

答案 1 :(得分:2)

你真正想做的是将C#方法映射到db函数HashBytes,这样做就像这样

[Function(Name = "HashBytes")]
[return: Parameter(DbType = "VarChar(100)")]
string HashBytes(string hashtype, string text)
{  .... }

详情请见:http://msdn.microsoft.com/en-us/library/bb386973.aspx

这将允许您在适当的LINQ中编写查询:

var q = from u in db.Users
        where u.Login == cn && u.PasswordHash == HashBytes("SHA1", pw)
        select u;

答案 2 :(得分:0)

您似乎错过了登录名和密码的模板字符串中的引号。

var user = db.ExecuteQuery<User>("select * from Users where Login = '{0}' and PasswordHash = HashBytes('SHA1', '{1}')", loginTextBox.Text.Trim(), passwordPasswordBox.Password).SingleOrDefault();