【问题标题】:C# Entity Framework Error Converting nvarchar to int by enumC# Entity Framework 错误通过枚举将 nvarchar 转换为 int
【发布时间】:2016-04-06 15:10:39
【问题描述】:

我收到以下错误时遇到问题:

Conversion failed when converting the nvarchar value 'HolidayRequest' to data type int.

我在实体框架中有一个继承结构。我的基本模型如下:

public abstract class Request
{
    public int ID { get; set; }
    public int EmployeeID { get; set; }
    public string Subject { get; set; }

    [Display(Name = "Date Requested")]
    public DateTime DateRequested { get; set; }
    [Display(Name = "Start Date")]
    public DateTime StartDateTime { get; set; }
    [Display(Name = "Return To Work Date")]
    public DateTime EndDateTime { get; set; }
    public RequestStatus Status { get; set; }
    public string Notes { get; set; }
    public int? ResponseID { get; set; }
    public RequestDiscriminator Discriminator { get; set; }

    [ForeignKey("EmployeeID")]
    public virtual Employee Employee { get; set; }
    [ForeignKey("ResponseID")]
    public virtual Response Response { get; set; }
}

当我尝试从数据库中检索数据时:

    public IQueryable<Request> GetPendingHolidayRequestsByEmployeeId(int employeeId)
    {
        var list = _context.Requests.Where(p => p.Discriminator == RequestDiscriminator.Holiday && p.EmployeeID == employeeId && p.Status == RequestStatus.NotProcessed);
        return list;
    }

这是发生错误的地方。

鉴于错误的上下文,我认为这是此枚举 public RequestDiscriminator Discriminator { get; set; } 的问题

枚举的结构是:

public enum RequestDiscriminator
{
    Holiday,
    Absence
}

实体框架正在发送的SQL语句是:

SELECT 
[Extent1].[ID] AS [ID], 
CASE WHEN ([Extent1].[Discriminator1] = N'AbsenceRequest') THEN '0X0X' ELSE '0X1X' END AS [C1], 
[Extent1].[EmployeeID] AS [EmployeeID], 
[Extent1].[Subject] AS [Subject], 
[Extent1].[DateRequested] AS [DateRequested], 
[Extent1].[StartDateTime] AS [StartDateTime], 
[Extent1].[EndDateTime] AS [EndDateTime], 
[Extent1].[Status] AS [Status], 
[Extent1].[Notes] AS [Notes], 
[Extent1].[ResponseID] AS [ResponseID], 
[Extent1].[Discriminator] AS [Discriminator]
CASE WHEN ([Extent1].[Discriminator1] = N'AbsenceRequest') THEN [Extent1].[ReasonCode] END AS [C2], 
CASE WHEN ([Extent1].[Discriminator1] = N'AbsenceRequest') THEN [Extent1].[TakenPaid] END AS [C3], 
CASE WHEN ([Extent1].[Discriminator1] = N'AbsenceRequest') THEN CAST(NULL AS float) ELSE [Extent1].[TotalDays] END AS [C4], 
CASE WHEN ([Extent1].[Discriminator1] = N'AbsenceRequest') THEN [Extent1].[Employee_EmployeeID] END AS [C5], 
CASE WHEN ([Extent1].[Discriminator1] = N'AbsenceRequest') THEN CAST(NULL AS int) ELSE [Extent1].[Employee_EmployeeID1] END AS [C6]
FROM [dbo].[Request] AS [Extent1]
WHERE ([Extent1].[Discriminator1] IN (N'AbsenceRequest',N'HolidayRequest')) AND (0 = [Extent1].[Discriminator]) AND (0 = [Extent1].[Status])

任何帮助将不胜感激,因为我完全被难住了。

更新

根据以下答案中的建议,我已从数据库中删除了两个鉴别器列并重新读取了我的。但是,SQL 查询似乎仍在寻找现在不存在的 Discriminator1 列。

【问题讨论】:

  • 可能是因为你的 nvarchar 值是 'HolidayRequest' 但你的枚举是 'Holiday'?
  • 我可以在 SQL 中看到,但我不知道这是从哪里来的,因此如何解决它
  • 可能调用您自己的专栏Discriminator 不是一个好主意,尤其是与TPH 结合使用。 EF 维护自己的 string 列,称为 Discriminator 以区分派生类,因此它可能在某处被硬编码(只是猜测)。

标签: c# entity-framework enums


【解决方案1】:

我已经设法解决了这个问题。答案是删除我创建的鉴别器列,并允许 EF 通过在 linq 查询中包含类型来确定类型,如下所示:

var test = _context.Requests.Where(r => r.EmployeeID == employeeId).OfType<AbsenceRequest>();

OfType() 似乎告诉 EF 查看该类型名称的鉴别器列,并且只返回该类型的数据。

【讨论】:

    【解决方案2】:

    看起来您在“Discriminator1”中有一个额外的列。您是否最初将该字段作为字符串,然后尝试将其转换为枚举?最好的选择可能是尝试完全丢弃该字段并确保它同时丢弃 Discriminator 和 Discriminator1。然后尝试将其添加回来。这可能发生在具有自定义映射时,因此可能会出现问题。

    【讨论】:

    • 好的,如果我从模型中删除属性并更新数据库,那么现在正在检索该表中的所有记录。但是,我如何才能仅获得属于 HolidayRequest 而不是 AbsenceRequest 的请求?
    • 查看数据库并确保两列都已从表中删除。然后将列添加回来并执行您正在执行的操作。出于某种原因,您只是有一个额外的列需要删除。
    • 好的,我明天上班时试试这个,如果可行,我会接受你的回答
    • 好的,我已经删除了 DIscriminator 和 Discriminator1 列。然后我阅读了我的鉴别器专栏。但是,查询仍在寻找 Discriminator1 并产生错误 Invalid column name 'Discriminator1'。有什么想法吗?
    猜你喜欢
    • 2017-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-02
    • 2011-05-09
    相关资源
    最近更新 更多