简体   繁体   English

不执行具有LinQ相关查询的MySQL实体框架

[英]MySQL Entity Framework With LinQ Correlated Query Not Executing

I am using Visual Studio 2012 with MySQL 5.7 Community Edition. 我将Visual Studio 2012与MySQL 5.7 Community Edition一起使用。 I am getting object reference not set to an instance of object on the below query. 我在以下查询中未将对象引用设置为对象的实例。

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();

In the above query If I get change 12345678 to dm.DocumentHandle, then getting object reference not set to an instance object. 在上面的查询中,如果将dm.DocumentHandle更改为12345678,则获取的对象引用未设置为实例对象。

Try with MS-SQL server , working fine. 尝试使用MS-SQL服务器,工作正常。

You get the error because FirstOrDefault() returns null, because there are no objects who's DocumentHandle equals dm.DocumentHandle . 由于FirstOrDefault()返回null,因为没有DocumentHandle等于dm.DocumentHandle对象,所以会出现dm.DocumentHandle Changing dm.DocumentHandle to 12345678 works because there is one matching element. dm.DocumentHandle更改为12345678dm.DocumentHandle ,因为有一个匹配的元素。

This line is the problem: 这行是问题所在:

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

C#'s Enumerable.FirstOrDefault() method returns either the first matching element of an enumerable, or, if there aren't any, the default value of the type. C#的Enumerable.FirstOrDefault()方法返回可枚举的第一个匹配元素,或者如果没有则返回该类型的默认值。 In the case of nullable types, FirstOrDefault() returns null if no elements are found. 对于可空类型,如果未找到任何元素,则FirstOrDefault()返回null。

The reason you get no error when you use 12345678 is because there is at least one matching value with that DocumentHandle . 使用12345678时不会出错的原因是,该DocumentHandle至少有一个匹配值。 However, when you change that to dm.DocumentHandle , no matching elements are found, causing FirstOrDefault to return null . 但是,将其更改为dm.DocumentHandle ,找不到匹配的元素,导致FirstOrDefault返回null Then you essentially do null.Remarks , which causes the error. 然后,您实际上执行了null.Remarks ,这会导致错误。

You should change your code to this: 您应该将代码更改为此:

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

There are two differences here: 这里有两个区别:

  1. Got rid of the where and moved the predicate to the FirstOrDefault call. 摆脱了位置,并将谓词移至FirstOrDefault调用。 This is just a cleaner way of doing what you were doing before. 这只是做以前工作的一种更清洁的方法。

  2. Added the ? 添加了? at the end of the FirstOrDefault call. FirstOrDefault调用结束时。 That is the null propagation operator . 那就是空传播算子

What it does is it turns this: 它的作用是这样的:

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

Into this: 变成这个:

int foo = bar?.foo;

Now, if there are matching elements, statusRemarks will be equal to the first one's Remarks . 现在,如果存在匹配的元素,则statusRemarks将等于第一个的Remarks Otherwise, statusRemarks will be null . 否则, statusRemarks将为null

EDIT: The null propagation operator was implemented in C# 6.0, which is .Net 4.6 onwards, so it won't work in .Net 4.0. 编辑:空传播运算符在C#6.0中实现,它是.Net 4.6及更高版本,因此在.Net 4.0中将不起作用。

You'll have to modify your query and implement a check, like so: 您必须修改查询并实施检查,如下所示:

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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM