.net Dapper枚举Map

vxf3dgd4  于 2023-06-07  发布在  .NET
关注(0)|答案(4)|浏览(217)

我需要帮助Map枚举与Dapper和Oracle。
我在Oracle中有一个字段,类型为NUMBER(1),必须转换为实体中的枚举。

public Status Status { get; set; }

状态是枚举:

public enum Status
{
    [Description("Inactive", "0")]
    Inactive = 0,

    [Description("Active", "1")]
    Active = 1,
 }

如何使用Dapper进行Map?

gupuwyp2

gupuwyp21#

对于整数或字符串表示,枚举应该是JustWork™。如果它不起作用,您必须更具体地说明它抛出的任何异常。例如,大声思考和纯粹的猜测,但是:IIRC Oracle习惯于将数字视为64位,我想知道枚举Map代码是否可以处理所有类型的数字转换。如果没有,那就是一个bug。
那么:它有效吗?

moiiocjp

moiiocjp2#

只是为了明确与健全的建议,在其他答案。您的数据库可能将数据存储在名为StatusId的列中,而您的对象的属性可能只是Status
我通常通过在SQL查询中使用别名来解决这个问题:
SELECT StatusId AS Status FROM Table
Dapper隐式地理解如何将int数据库字段Map到C#枚举。我通常给予我的枚举显式的值,使事情尽可能清楚,例如。

public enum Status
{
   Active = 1,
   Inactive = 2
}
elcex8rz

elcex8rz3#

在使用dapper时,我无法使可空枚举工作。
为了解决这个问题,我创建了两个类:对象模型和SQL模型。
SQL模型是对象模型的一个简单版本,使用枚举作为字符串,它们通过该字符串保存在数据库中。对象模型有一个以SQL模型作为输入的构造函数。

class ThingSQLModel
{
    public int? Id;

    public String? ThingType;

 ....

}

class Thing
{
    public int? Id;

    public EnumThingType? ThingType{ get; set; }

 ....

    public Thing(ThingSQLModel)
    {
        Id = output.Id;

        ThingType= EnumHelper.TryParseNullable<EnumThingType>(output.ThingType);
    }
}

关于TryParseNullable<EnumThingType>,请参见:Parsing value into nullable enumeration
也许有一种更好的方法,即显式地覆盖此类型的默认解析?嗯,我会试验一下,然后给出答案。

xwbd5t1u

xwbd5t1u4#

除了现有的答案,还有另一个特殊的情况。
我发现,如果枚举Map到模型内部的属性,并且您的Query<Model>是该模型类型,Dapper会自动Map枚举。
但是,当您直接执行Query<MyEnum>时,它会抛出一个异常,并期望数据库返回一个int32。
为了解决这个问题,我做了一个小EnumWrapper,如下所示:

public class EnumWrapper<T> where T:struct
{
    public T Value { get; set; }
}

然后像这样继续查询:

var sql = @"SELECT E.[Status] AS [Value] FROM [Exmaple].Example E";

    var connection = await this.GetConnection();
    
    var status = await connection.QuerySingleAsync<EnumWrapper<TheEnum>>(sql);

    return status.Value;

SQL别名必须与EnumWrapper中的属性匹配,这一点很重要。在这个例子中,它是Value

相关问题