我有以下枚举和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,
};
不幸的是我收到错误“无法将类型'字符串'隐式转换为'Model.Gender'”
我想将查询的字符串从实体框架转换为我的Gender枚举,并将其分配给我的POCO类。
答案 0 :(得分:4)
实体框架不支持枚举。亚历克斯·詹姆斯有一种解决方法,但它非常复杂。
相反,我更喜欢这样做:
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; }
}
}
它基本上是实际值的钩子/包装器。在您的数据库中,将性别存储为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
的字节字段,您还可以访问枚举属性GenderType
。
这能解决您的问题吗?
答案 1 :(得分:1)
我熟悉的实体框架不支持枚举。 EF使用您的查询表达式创建一个SQL语句,然后将其发送到服务器,如果它无法创建某个操作的SQL等效项,则会为该操作抛出NotSupportedException。如果您希望返回一小组数据,可以使用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();
答案 2 :(得分:0)
<击> 尝试击>
<击>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
答案 3 :(得分:0)
if (Enum.IsDefined(typeof(Gender), genderstring))
Gender g = (Gender) Enum.Parse(typeof(Gender), genderstring, true);
else
//Deal with invalid string.