【问题标题】:Cast int to enum from sql query C# Entity Framework从 sql 查询 C# Entity Framework 将 int 转换为枚举
【发布时间】:2017-10-23 23:27:31
【问题描述】:

如何以NewUnitPhaseStatus 作为枚举返回IEnumerable

在 SQL 中,值“NewUnitPhaseStatus”存储为 int。如果我只是返回查询,那么当我尝试提取该值时,它只是说 DBcontext 已被处置。但是如果我尝试将查询结果转换为列表,那么它说 int 不能转换为类型 NewUnitPhaseStatus(枚举类型)。

public IEnumerable<UnitPhaseLog> GetAllForUnitPhase(long unitPhaseId)
{
    using (var db = new DbContext(_connStringKey))
    {
         var querys = from s in db.UnitPhaseLogs 
                      where s.UnitPhaseId == unitPhaseId 
                      select s;

          return querys;
     }
}

如果使用 foreach 语句将每一行转换为枚举,则会出错,因为 var 查询属于 UnitPhaseLog 类,且 NewUnitPhaseStatus 等于枚举。

错误信息:

如果有人尝试将结果转换为列表。

“UnitPhaseLog”上的“NewUnitPhaseStatus”属性无法设置为“System.Int64”值。您必须将此属性设置为“Core.UnitPhaseStatus”类型的非空值。

如果尝试自己返回查询结果:

操作无法完成,因为 DbContext 已被释放。

代码:

public enum UnitPhaseStatus
{
    [Display(Name = "No Status")]
    NoStatus,
    [Display(Name = "Not Ready")]
    NotReady,
    [Display(Name = "Materials Needed")]
    MaterialsNeeded,
    [Display(Name = "Ready For Work")]
    ReadyForWork,
    [Display(Name = "Work In Progress")]
    WorkInProgress,
    [Display(Name = "Ready")]
    ReadyForQc,
    [Display(Name = "Approved")]
    Approved,
    [Display(Name = "Rejected")]
    Rejected,
}

【问题讨论】:

  • 你在说这条线? UnitPhaseStatus UnitPhaseStatus = query.NewUnitPhaseStatus;
  • 请显示定义 UnitPhaseStatus 的代码。您的枚举值应与 SQL 定义匹配。
  • 看看@DigiFriend 的回答。在您的枚举定义中,您必须添加 = VALUE: NoStatus = 0, NotReady = 1, MaterialsNeeded = 2 WHERE 0,1 和 2 将匹配 SQL 列中的值。
  • 有什么理由不能简单地返回querys
  • 您的 ORM(实体框架?)为您进行转换。

标签: c# sql entity-framework


【解决方案1】:

您需要将数据库的返回值转换为枚举类型。

unit.NewUnitPhaseStatus = (UnitPhaseStatus)UnitPhaseStatus;

不过,您可以直接执行此操作,而不必通过额外的局部变量。

所以,而不是:

UnitPhaseStatus UnitPhaseStatus = query.NewUnitPhaseStatus;
unit.NewUnitPhaseStatus = UnitPhaseStatus;

你可以使用:

unit.NewUnitPhaseStatus = (UnitPhaseStatus)query.NewUnitPhaseStatus;

【讨论】:

  • 代码在 foreach 语句处中断,因为 var 查询的类型为 NewUnitPhaseStatus,它是一个枚举
  • 我认为你没有关注。好的。 UnitPhaseLog.NewUnitPhaseStatus 是什么类型? query.NewUnitPhaseStatus 是什么类型(不是名称 - 类型)?类型需要匹配。如果没有,您需要进行投射。
【解决方案2】:

这是假设您使用的是实体框架,所以如果您不这样做,请随意忽略。

与其担心将 Int 转换为枚举或将枚举转换为 Int,更好的解决方案可能是更改实体以将该列直接绑定到枚举并让框架为您进行转换。

【讨论】:

  • 那么你如何查询结果呢?
  • 如果您解决了遇到的转换错误,您应该能够以列表的形式获得结果。
【解决方案3】:

您无需弄乱foreach 循环-您的querys 已经是正确的类型,因此如果不是null,则返回它。

public IEnumerable<UnitPhaseLog> GetAllForUnitPhase(long unitPhaseId)
{
    using (var db = new DbContext(_connStringKey))
    {
        var querys = from s in db.UnitPhaseLogs where s.UnitPhaseId == unitPhaseId select s;

        List<UnitPhaseLog> UnitPhaseLogList = new List<UnitPhaseLog>();
        if (null == querys) return UnitPhaseLogList;

        return querys;
    }
}

【讨论】:

  • “UnitPhaseLog”上的“NewUnitPhaseStatus”属性无法设置为“System.Int64”值。您必须将此属性设置为“Core.UnitPhaseStatus”类型的非空值。
  • 这表明您的UnitPhaseLog.NewUnitPhaseStatuslong,而实际上它应该是Core.UnitPhaseStatus。这可能是您所有问题的根源。
  • 这是一个 UnitPhaseStatus。我注意到,如果我在检索数据之前没有将 IEnumerable 转换为列表,那么它表示数据已被释放。
  • 根据我的经验,即使我只是返回查询(例如您在上面的答案中的情况),数据也无法访问,因为它已被处置。
  • 我在问题中展示了 UnitPhaseLog.NewUnitPhaseStatus 的类
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-21
  • 1970-01-01
  • 2012-07-12
相关资源
最近更新 更多