【问题标题】:Including an optional navigation property, where the navigation property Id is the same as the entity's primary key包括一个可选的导航属性,其中导航属性 Id 与实体的主键相同
【发布时间】:2013-07-07 12:29:41
【问题描述】:

所以我在创建查询时遇到了问题(好吧,我可以创建查询,但是 Entity Framework 在尝试加载属性时会中止它)。

我有两个实体:Contact 和 ExternalContactExtension。

联系方式

联系方式

是内部

...一些其他数据...

ExternalContactExtension

联系方式

...一些其他数据...

现在,两个表中的 contactId 相同,但并非所有联系人都是外部联系人(由 IsInternal 指定)并具有外部联系人扩展名。

所以问题是当我运行查询并尝试包含外部联系扩展名时。由于 ContactId 既是主键又是外键,所以它不能为空。我认为 EF 认为这意味着它存在(即使在导航属性上它被列为零或一)。如果我有任何没有外部联系分机的内部联系人,这会导致我的查询被中止。

有没有办法解决这个问题?还是我必须单独抓取外部联系人扩展实体?

编辑:我的模型图片:

失败的查询(通常更多的过滤/包含,但包含 ExternalContactExtension 似乎是唯一可以确定它是否失败的东西):

            DataSupplier.GetMany<Contact>(
                x => x.Active,
                x => x.ExternalContactExtension

                ).ToList();

GetMany 定义(技术上,由中间类调用,但这只是传递参数):

    public virtual IEnumerable<TEntity> GetMany<TEntity>(Expression<Func<TEntity, bool>> where, params Expression<Func<TEntity, object>>[] includeProperties)
        where TEntity : class
    {
        IDbSet<TEntity> set = this.context.Set<TEntity>();

        var query = set.IncludeMultiple(includeProperties).AsQueryable<TEntity>();

        query = query.Where(where);
        this.queryString = "";
        this.queryString = query.ToString();
        List<TEntity> list = query.ToList();
        return list;
    }

错误信息:

在您尝试使用属性之前,它实际上不会抛出任何消息(然后我得到一个空引用异常)。

另一个编辑:

我做了一个 SQL 配置文件,EF 正在正确生成 SQL:

SELECT 
[Extent1].[ContactId] AS [ContactId], 
[Extent1].[EmployeeId] AS [EmployeeId], 
[Extent1].[IsInternal] AS [IsInternal], 
[Extent1].[GroupId] AS [GroupId], 
[Extent1].[OldSupplierId] AS [OldSupplierId], 
[Extent1].[Active] AS [Active], 
[Extent1].[InsertUserId] AS [InsertUserId], 
[Extent1].[InsertDate] AS [InsertDate], 
[Extent1].[UpdateUserId] AS [UpdateUserId], 
[Extent1].[UpdateDate] AS [UpdateDate], 
[Extent2].[ContactId] AS [ContactId1], 
[Extent2].[Salutation] AS [Salutation], 
[Extent2].[FirstName] AS [FirstName], 
[Extent2].[MiddleInitial] AS [MiddleInitial], 
[Extent2].[LastName] AS [LastName], 
[Extent2].[Phone] AS [Phone], 
[Extent2].[Fax] AS [Fax], 
[Extent2].[Title] AS [Title], 
[Extent2].[Department] AS [Department], 
[Extent2].[Email] AS [Email], 
[Extent2].[Address] AS [Address], 
[Extent2].[City] AS [City], 
[Extent2].[Territory] AS [Territory], 
[Extent2].[Country] AS [Country]
FROM  [DataSupplier].[Contact] AS [Extent1]
LEFT OUTER JOIN [DataSupplier].[ExternalContactExtension] AS [Extent2] ON [Extent1].[ContactId] = [Extent2].[ContactId]
WHERE [Extent1].[Active] = 1

(它正确地进行了外连接,并且此 SQL 确实返回了正确的结果/它运行)。所以它是 Entity Framework 正在处理破坏它的地方。

【问题讨论】:

  • 您确定导航属性设置为Contact 上的“0..1”和ExternalContactExtension 上的“1”吗?如果是这样,请提供有关正在中止的查询的更多信息 - 堆栈跟踪、确切的错误消息等。
  • @Bobson 更新了我的帖子
  • 不错的更新!如果你把x =&gt; x.ExternalContactExtension 线去掉可以吗?还是它仍然中止?
  • @Bobson 如果我取出线路它可以工作,如果该线路在那里则不起作用。这实际上是一个更大查询的缩减版本(包括该行会导致它中止)。包含该查询的其他属性的工作。
  • 我怀疑set.IncludeMultiple() 处理不当。但是ExternalContactExtensionID(我假设该字段的名称)也应该可以为空,以防万一。

标签: c# entity-framework


【解决方案1】:

根据聊天,解决此问题的最佳方法可能是创建“缺失”ExternalContactExtensionID 字段,该字段可以是 NULL

您只需对数据库稍作调整即可做到这一点。创建一个计算字段并使用公式:

CASE WHEN IsExternal THEN ContactID ELSE NULL END

然后 EF 会看到它所期望的,它应该是好的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-15
    • 1970-01-01
    • 2015-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多