【问题标题】:Entity Framework Exception in Foreign Key 2外键 2 中的实体框架异常
【发布时间】:2014-08-21 01:27:15
【问题描述】:

您好,我有两张这样的表:

public class TableA
{
    public int IdTableA { get; set; }

    public string OtherInfo { get; set; }

    public int? IdTableB { get; set; }

    public TableB TableB { get; set; }
}

public class TableB
{
    public TableB()
    {
        TableAs = new HashSet<TableA>();
    }

    public int IdTableB { get; set; }

    public string Description { get; set; }

    public ICollection<TableA> TableAs { get; set; }
}

TableATableB的外键映射如下:

this.HasOptional(t => t.TableB)
    .WithMany(t => t.TableAs)
    .HasForeignKey(d => d.IdTableB);

现在我正在尝试从TableA 中选择一些数据:

context
    .TableA
    .Select(s => new TableA_DTO
    {
        IdTableA = s.IdTableA,
        OtherInfo = s.OtherInfo,
        IdTableB = s.IdTableB,
        TableB = new TableB_DTO
        {
            IdTableB = s.TableB.IdTableB,
            Description = s.TableB.Description
        }
    }).ToList();

当我在TableA 中有一行IdTableB = null 时的问题。我得到了这个例外:

转换为值类型“Int32”失败,因为具体化值为空。结果类型的泛型参数或查询必须使用可为空的类型。

如何使用实体框架选择此信息?

【问题讨论】:

    标签: c# .net linq entity-framework


    【解决方案1】:

    你需要一个空检查:

    context
        .TableA
        .Select(s => new TableA_DTO
        {
            IdTableA = s.IdTableA,
            OtherInfo = s.OtherInfo,
            IdTableB = s.IdTableB,
            TableB = new TableB_DTO
            {
                IdTableB = (s.TableB != null) ? s.TableB.IdTableB : null,
                Description = (s.TableB != null) ? s.TableB.Description : null
            }
        }).ToList();
    

    或者可能:

    TableB = s.TableB != null 
            ? new TableB_DTO
            {
                IdTableB = (s.TableB != null) ? s.TableB.IdTableB : null,
                Description = (s.TableB != null) ? s.TableB.Description : null
            }
            : null
    

    编辑:根据下面的 cmets,该错误是因为上下文或 SQL 不知道 TableA_DTO。您需要做的是首先有效地获取结果集:

    var data = context.TableA.Include("TableB").ToList(); 'ToList executes
    

    然后,选择它并转换为所需的类型:

    //This is a LINQ to Objects operation now, which can do any kind of data transformation
    var results = data.Select(s => new TableA_DTO { ... });
    

    这可行,但您必须确保您没有通过实体框架在以下迭代中检索相关数据而遇到选择 N+1 场景。

    【讨论】:

    • 在第一种情况下,TableB_DTO.IdTableB 不为 null (int)。在第二次抛出异常:无法创建类型为“TableA_DTO”的常量值。此上下文仅支持原始类型(“例如 Int32、String 和 Guid”)。
    • 它正在尝试将 TableA_DTO 转换为 SQL,但不能。以上编辑。
    • 谢谢。这不是最干净的解决方案,但似乎是唯一的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2018-12-18
    • 2011-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    相关资源
    最近更新 更多