实体框架中的自定义非基本类型代码优先4.1

时间:2011-07-22 18:37:59

标签: passwords entity-framework-4.1 code-first custom-type

我有这种自定义类型:

public struct PasswordString
{
    private string value;

    public PasswordString(string value)
    {
        this.value = MD5.CalculateMD5Hash(value);
    }

    public string Value
    {
        get { return this.value; }
        set { this.value = MD5.CalculateMD5Hash(value); }
    }

    public static implicit operator PasswordString(string value)
    {
        return new PasswordString(value);
    }

    public static implicit operator string(PasswordString value)
    {
        return value.Value;
    }

    public static bool operator ==(string x, PasswordString y)
    {
        return x.CompareTo(y) == 0;
    }

    public static bool operator !=(string x, PasswordString y)
    {
        return x.CompareTo(y) != 0;
    }

    public override string ToString()
    {
        return Value;
    }
}

public static class MD5
{
    public static string CalculateMD5Hash(string input)
    {
        System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
        byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
        byte[] hash = md5.ComputeHash(inputBytes);

        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        for (int i = 0; i < hash.Length; i++)
        {
            sb.Append(hash[i].ToString("X2"));
        }
        return sb.ToString();
    }
}

所以,我想在我的Entity Framework项目中使用这种类型。如何将类型映射为像字符串一样工作。

public class User
{
    public int Id { get; set; }
    public string Username { get; set; }
    public PasswordString Password { get; set; }
}

使用样本:

User user = new User()
{
    Username = "steve",
    Password = "apple"
};

System.Console.WriteLine(user.Password == "apple");
System.Console.WriteLine(user.Password);

此代码生成:

True
1F3870BE274F6C49B3E31A0C6728957F

我的目标是查询实体框架,使其具有以下内容:

var q = from u in users
        where u.Username == "steve" && u.Password == "apple"
        orderby u.Username
        select u;

那么,我永远不需要加密密码,但它会被加密存储在数据库中。

我正在尝试将此类与EF一起使用,但没有成功。使用Entity Framework 4.1可以实现这一目标吗?

2 个答案:

答案 0 :(得分:2)

实体框架不支持类型转换器或任何其他方式将简单数据库列映射到您的自定义类型,并且此功能甚至尚未计划用于下一版本。所以你的问题的答案是:不可能。

答案 1 :(得分:1)

在LINQ to Entities查询中,不可能将您的类(或结构)用作复杂类型。我命令执行这个比较...

u.Password == "apple"

...必须调用构造函数,然后依次调用MD5.CalculateMD5Hash。此方法无法转换为SQL,查询将引发异常。 LINQ to Entities可能甚至不支持任何重载运算符(如==) - 出于同样的原因:EF无法将其转换为SQL。