【问题标题】:MySQL Entity Framework With LinQ Correlated Query Not Executing具有 LinQ 相关查询未执行的 MySQL 实体框架
【发布时间】:2017-08-12 08:01:32
【问题描述】:

我正在使用带有 MySQL 5.7 社区版的 Visual Studio 2012。我在下面的查询中得到对象引用未设置为对象的实例。

var oList = (
    from dm in dbContext.document_master
    join um in dbContext.user_master on dm.Alocated_CAA equals um.UserId
    where (dm.DocumentHandle != null)
    select new TaskLogReport
    {
        documentDate = dm.Document_Date,
        documentHandle = dm.DocumentHandle,
        fileNumber = dm.FileNumber,
        statusRemarks = dbContext.statushistories
            .Where(x => x.DocumentHandle == 12345678).FirstOrDefault().Remarks
    }).ToList();

在上述查询中,如果我将 12345678 更改为 dm.DocumentHandle,则获取的对象引用未设置为实例对象。

尝试使用 MS-SQL 服务器,工作正常。

【问题讨论】:

    标签: c# mysql linq visual-studio-2012 linq-to-sql


    【解决方案1】:

    您收到错误是因为 FirstOrDefault() 返回 null,因为没有对象 DocumentHandle 等于 dm.DocumentHandle。将dm.DocumentHandle 更改为12345678 有效,因为有一个匹配元素。

    这行是问题所在:

    .Where(x => x.DocumentHandle == 12345678).FirstOrDefault().Remarks
    

    C# 的Enumerable.FirstOrDefault() 方法返回可枚举的第一个匹配元素,或者,如果没有,则返回该类型的默认值。对于可空类型,如果没有找到任何元素,FirstOrDefault() 将返回 null。

    使用12345678 时没有出现错误的原因是因为至少有一个与DocumentHandle 匹配的值。但是,当您将其更改为 dm.DocumentHandle 时,找不到匹配的元素,导致 FirstOrDefault 返回 null。然后你基本上做null.Remarks,这会导致错误。

    你应该把你的代码改成这样:

    .FirstOrDefault(x => x.DocumentHandle == dm.DocumentHandle)?.Remarks
    

    这里有两个区别:

    1. 去掉 where 并将谓词移动到 FirstOrDefault 调用。这只是一种更简洁的方式来做你之前所做的事情。

    2. FirstOrDefault 调用的末尾添加了?。那是null propagation operator

    它的作用是:

    int foo;
    if (bar != null)
    {
        foo = bar.foo;
    }
    

    进入这个:

    int foo = bar?.foo;
    

    现在,如果有匹配的元素,statusRemarks 将等于第一个的Remarks。否则,statusRemarks 将是 null

    编辑: null 传播运算符是在 C# 6.0 中实现的,即 .Net 4.6 及更高版本,因此它在 .Net 4.0 中不起作用。

    您必须修改查询并实施检查,如下所示:

    var oList = (
        from dm in dbContext.document_master
        join um in dbContext.user_master on dm.Alocated_CAA equals um.UserId
        where (dm.DocumentHandle != null && dbContext.statushistories.Count(x => x.DocumentHandle == dm.DocumentHandle) > 0)
        select new TaskLogReport
        {
            documentDate = dm.Document_Date,
            documentHandle = dm.DocumentHandle,
            fileNumber = dm.FileNumber,
            statusRemarks = dbContext.statushistories.First(x.DocumentHandle == dm.DocumentHandle).Remarks
        }).ToList();
    

    【讨论】:

    • 我正在使用 .Net Framework 4.0 & null 编程运算符不起作用。在 MS-SQL 2005 上复制相同的代码集后,它可以正常工作,并且相同的代码不适用于 MySQL。我尝试安装不同的连接器,但仍然存在相同的问题
    猜你喜欢
    • 1970-01-01
    • 2021-12-03
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-07
    • 1970-01-01
    相关资源
    最近更新 更多