在linq查询MVC 2.0中将字符串解析为poco类枚举

发布于 2024-10-04 15:12:49 字数 673 浏览 0 评论 0原文

我有以下枚举和 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’ '"

我想将从实体框架查询的字符串转换为我的 Gender 枚举并将其分配给我的 POCO 类。

I have the following enum and POCO class

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; }
}

I would like to perform a "get all people" query in my repository such that it would look something like this:

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

Unfortunately I get an error "Cannot implicitly convert type 'string' to 'Model.Gender'"

I would like to convert the string which is being queried from the entity framework to my Gender enum and assign it to my POCO class.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

自在安然 2024-10-11 15:12:49

实体框架不支持枚举。 Alex James 有一个解决方法,但是非常复杂。

相反,我更喜欢这样做:

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 设置了字节字段,您还可以访问枚举属性<代码>性别类型。

这能解决你的问题吗?

Enums are not supported in Entity Framework. There is a workaround by Alex James, but it's quite involved.

Instead, i prefer to do this:

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; }
    }
}

It's basically a hook/wrapper for the actual value. In your database, store Gender as a tinyint (which maps to byte on the conceptual side).

Then you can use a byte enum to map to and from the model property:

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

But then if you access that ViewModel, because your setting the byte field for Gender, you will also have access to the enum property GenderType.

Does that solve your problem?

短叹 2024-10-11 15:12:49

我熟悉的实体框架不提供对枚举的支持。 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();

The Entity Framework that I am familiar with does not provide support for enums. EF uses your query expression to create an SQL statement that it then sends to the server, if it cannot create the SQL equivalent of some operation it will throw a NotSupportedException for that operation. If you are expecting to return a small set of data you can separate from the Entity Framework by creating an object in memory using the ToArray method.

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

This will create a sequence of entities in memory. Any further query statements will then be in the realm of LINQ to Objects which allows parsing of strings into enums:

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

Or you could even break it out into a foreach loop:

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();
临走之时 2024-10-11 15:12:49
   if (Enum.IsDefined(typeof(Gender), genderstring))
      Gender g = (Gender) Enum.Parse(typeof(Gender), genderstring, true);
   else
      //Deal with invalid string.
   if (Enum.IsDefined(typeof(Gender), genderstring))
      Gender g = (Gender) Enum.Parse(typeof(Gender), genderstring, true);
   else
      //Deal with invalid string.
转身泪倾城 2024-10-11 15:12:49

<罢工>
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


try

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

To parse the string as one of the enums

here's a workaround but it means changing your nice and clean POCO

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文