Разобрать строку в перечисление класса poco в запросе linq MVC 2.0 - PullRequest
2 голосов
/ 26 ноября 2010

У меня есть следующий enum и класс POCO

public enum Gender
{
    Male,
    Female,
    Unknown
}

public class Person
{
    public int PersonId { get; set; }
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public Gender? Gender { get; set; }
}

Я бы хотел выполнить запрос «получить всех людей» в моем хранилище, чтобы он выглядел примерно так:

return from p in _db.People
       select new Model.Person
       {
          PersonId = p.PersonId,
          LastName = p.LastName,
          FirstName = p.FirstName,
          Gender = p.Gender,
       };

К сожалению, я получаю сообщение об ошибке "Невозможно неявно преобразовать тип 'string' в 'Model.Gender'"

Я хотел бы преобразовать строку, которая запрашивается из структуры сущностей к моему половому перечислению и назначить его моему классу POCO.

Ответы [ 4 ]

4 голосов
/ 26 ноября 2010

Перечисления не поддерживаются в Entity Framework. Алекс Джеймс предлагает обходной путь, но он довольно сложный.

Вместо этого я предпочитаю делать это:

public enum Gender : byte
{
    Male = 1,
    Female,
    Unknown
}

public class Person
{
    public int PersonId { get; set; }
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public byte Gender { get; set; } // this is the EF model property
    public Gender GenderType // this is an additional custom property
    { 
        get { return (Gender) Gender; }
        set { Gender = (byte)value; }
    }
}

Это в основном хук / обертка для фактического значения. В вашей базе данных храните Gender как tinyint (что соответствует концептуальной стороне byte).

Затем вы можете использовать байтовое перечисление для сопоставления со свойством модели:

return from p in _db.People
       select new Model.Person
       {
          PersonId = p.PersonId,
          LastName = p.LastName,
          FirstName = p.FirstName,
          Gender = p.Gender, // sets byte
       };

Но тогда, если вы получите доступ к этой ViewModel, поскольку вы устанавливаете поле байта для Gender, у вас также будет доступ к свойству enum GenderType.

Решает ли это вашу проблему?

1 голос
/ 07 июня 2012

Платформа Entity Framework, с которой я знаком, не обеспечивает поддержку перечислений. EF использует ваше выражение запроса для создания оператора SQL, который затем отправляет на сервер. Если он не может создать эквивалент SQL какой-либо операции, он генерирует исключение NotSupportedException для этой операции. Если вы ожидаете вернуть небольшой набор данных, вы можете отделиться от Entity Framework, создав объект в памяти с помощью метода ToArray.

var myEntities = (from entity in _db.Entities
                  where /* condition */
                  select entity)
                        .ToArray();

Это создаст последовательность объектов в памяти. Все последующие операторы запроса будут находиться в области LINQ to Objects, что позволяет анализировать строки в перечислениях:

return from myEntity in myEntities
       select new MyDataContract
       {
            ID = myEntity.ID,
            Gender g = (Gender)Enum.Parse(typeof(Gender), myEntity.Gender, true)
       };

Или вы можете даже разбить его на foreach цикл:

List<MyDataContract> myDataContracts = new List<MyDataContract>();
foreach (var myEntity in myEntities)
{
    var dataContract = new MyDataContract { ID = myEntity.ID };

    if (Enum.IsDefined(typeof(Gender), myEntity.Gender))
        dataContract.Gender = (Gender)Enum.Parse(typeof(Gender), myEntity.Gender, true);

        myDataContracts.Add(dataContract);
}

return myDataContracts.AsEnumerable();
0 голосов
/ 26 ноября 2010
   if (Enum.IsDefined(typeof(Gender), genderstring))
      Gender g = (Gender) Enum.Parse(typeof(Gender), genderstring, true);
   else
      //Deal with invalid string.
0 голосов
/ 26 ноября 2010

try

Gender = p.Gender != null ? (Gender)Enum.Parse(typeof(Gender), p.Gender) : (Gender?)null;

Чтобы проанализировать строку как одно из перечислений

вот обходной путь, но это означает изменение вашего красивого и чистого POCO

http://blogs.msdn.com/b/alexj/archive/2009/06/05/tip-23-how-to-fake-enums-in-ef-4.aspx

...