Пользовательский не примитивный тип в коде Entity Framework сначала 4.1 - PullRequest
1 голос
/ 22 июля 2011

У меня есть этот пользовательский тип:

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

Моя цель - сделать запрос к Entity Framework, чтобы получить что-то вроде этого:

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

Итак, мне никогда не нужно шифровать пароль, но он будет храниться в зашифрованном виде в базе данных.

Я пытаюсь использовать этот класс с EF, но безуспешно. Есть способ добиться этого с Entity Framework 4.1?

Ответы [ 2 ]

2 голосов
/ 23 июля 2011

Entity Framework не поддерживает преобразователи типов или любой другой способ сопоставления простого столбца базы данных с вашим пользовательским типом, и такая функция даже еще не запланирована на следующий выпуск. Таким образом, ответ на ваш вопрос: не возможно.

1 голос
/ 23 июля 2011

Невозможно использовать ваш класс (или структуру) как сложный тип в запросе LINQ to Entities.Я приказываю выполнить это сравнение ...

u.Password == "apple"

... должен быть вызван конструктор, который в свою очередь вызывает MD5.CalculateMD5Hash.Этот метод нельзя перевести на SQL, и запрос выдаст исключение.Вполне вероятно, что LINQ to Entities даже не поддерживает какой-либо перегруженный оператор (например, ==) - по той же причине: EF не может перевести его в SQL.

...