将 EF 属性分配给变量时"Object reference not set to an instance of an object"异常



当我试图将EF对象模型的一个属性分配给变量时,我得到了一个"Object reference not set to a instance of a Object"异常,但我不知道为什么,因为EF对象肯定包含数据,并且可以在Immediate Window中访问。

我调用以下代码从特定组织获取数据:

var organizationModelFromDb = this.DbContext.Organizations.
SingleOrDefault(o => o.OrganizationId == 
organizationEditViewModel.Organization.OrganizationId);

这肯定会返回数据,因为当我将鼠标悬停在organizationModelFromDb对象上时,当展开工具提示时,我可以看到显示的数据。当我键入时,我也可以访问数据

organizationModelFromDb.MembershipType

Immediate Window中,但当我尝试从我的对象模型中分配此属性时,如下所示:

var membershipType = organizationModelFromDb.MembershipType;

我得到了提到的例外。

这个控制器的方法中的一切都如预期的那样工作,但我正在引入新功能,但我遇到了这个问题。

任何可能发生的事情。我敢肯定,在我的项目中,我正在使用相同的技术将EF数据分配给变量,但无论出于何种原因,它在这种方法中都不起作用。

我错过了什么?

更新-1:

这不是一个重复的问题。引用的文章处理了对象实际上可能为null的事实,以及如何最好地处理每个场景,但正如所解释的,我的对象实际上不是null。数据正在返回,并且可以通过immediate window和工具提示获得。

更新-2

这是我从immediate window:调用"organizationModelFromDb"时得到的数据

{System.Data.Entity.DynamicProxies.
OrganizationModel_2AEF19E09C5699B8E172F0AA73D6DB
71945EF111ADF7AE5EAEB3AD073A15D5A3}
AdditionalDetails:
{System.Data.Entity.DynamicProxies.OrganizationAddition_
05739F8DE2F5D549B3A7FC852AC32ED9C002953ED41AAA7751B12289E23D8A6C}
AutoImport: false
Members: Count = 1
MembershipType: Full
OrganizationId: "4be433d5-48a9-4891-a008-c70fe4cfoie3"
OrganizationName: "My Company"
StatusType: Approved
Website: ""
_entityWrapper: {System.Data.Entity.Core.Objects.Internal.EntityWrapperWithoutRelationships<System.Data.Entity.DynamicProxies.OrganizationModel_2AEF19E09C5699B8E172F0AA73D6DB71945EF111ADF7AE5EAEB3AD073A15D5A3>}

正如您所看到的,对象中有数据。

但如前所述,当我调用这行代码时:

var membershipType = organizationModelFromDb.MembershipType;

在我的代码中,我得到了以下StackTrace:的异常

"System.NullReferenceException:对象引用未设置为对象的实例。

位于C:\Work\Mywebsite\Controllers\OrganizationsController.cs:line 349"中的Mywebsite.Controllers.OrganizationsController.d_8.MoveNext()

希望这能帮助解决我的问题。

更新-3

我删除了本次更新中最初提供的代码,以保持整洁,而不是提供另一次更新,但下面的代码是我的控制器中包含的完整代码,但请注意,为了可读性,我删除了不必要的代码:

var organizationModelFromDb = await this.DbContext.Organizations
.FirstOrDefaultAsync<OrganizationModel>(o => o.OrganizationId ==
organizationEditViewModel.Organization.OrganizationId);
if (ReferenceEquals(organizationModelFromDb, null))
return HttpNotFound();
organizationModelFromDb.StatusType = StatusType.Approved;
var memberModelsFromDb =
this.DbContext.Members.Where(
m => m.OrganizationId == 
organizationEditViewModel.Organization.OrganizationId).ToList();
if (memberModelsFromDb.Count > 0)
{
foreach (var memberModel in memberModelsFromDb.ToList())
{
var user = new ApplicationUser
{
UserName = memberModel.Email,
Email = memberModel.Email,
UserType = UserType.IsMember
};
var password = RandomPassword.Generate();
var result = await this.UserManager.CreateAsync(user, password);
if (result.Succeeded)
{
await this.UserManager.AddToRoleAsync(user.Id, JoiffRoles.IsMember);
try
{
var membershipType = organizationModelFromDb.MembershipType;
}
catch (Exception e)
{
Console.WriteLine(e);
}
string code = await this.UserManager.
GenerateEmailConfirmationTokenAsync(user.Id);
string codeHtmlVersion = HttpUtility.UrlEncode(code);
new Thread(async () =>
{
await CustomEmailService.
SendConfirm(this, Request, user, codeHtmlVersion);
}).Start();
}
}
}

现在,正如您所看到的,这个代码没有什么特别之处。我检查一个组织是否存在,然后获取该组织的所有成员,然后循环遍历每个成员,创建一个用户并向数据库中添加角色。创建成功后,它会向新创建的用户发送一封带有凭据信息的电子邮件。

现在奇怪的是,上面的代码中出现了异常"对象引用未设置为对象的实例",但不知何故,如果我对代码的任何一部分进行注释,都不会发生这种情况:

1) 删除try/catch上方的所有内容,但保留try-catch下方的电子邮件部分:

var password = RandomPassword.Generate();
var result = await this.UserManager.CreateAsync(user, password);
if (result.Succeeded)
{
await this.UserManager.AddToRoleAsync(user.Id, JoiffRoles.IsMember);
…
}

2) 删除电子邮件部分

new Thread(async () =>
{
await CustomEmailService.SendConfirm(this, 
Request, user, codeHtmlVersion);
}).Start();

我知道这听起来很荒谬,我已经一遍又一遍地研究过了,如果我保持代码原样,我在尝试将变量设置为OrganizationFromDb.MembershipType时会出现这个错误。如果我删除上面提到的任何一个部分,一切都会按预期进行。

正如@CamiloTerevinto所提到的,我确实相信它与一些尚未完全提取、仅部分建造的东西有关,但这两个部分是如何影响这一点的?

有什么建议吗?

我还没有弄清楚为什么会发生这种情况,也没有弄清楚在删除更新中提到的代码片段时为什么会起作用,但我很确定这确实与@CamiloTerevinto之前提到的EF实体仅部分构建/查询有关。

我只能假设,在Immediate window和/或通过工具提示显示数据的行为与在运行时将数据分配给变量时使用数据的行为不同。

无论如何,与其试图修复和/或弄清楚为什么删除这些代码片段会奏效,我想我应该尝试一种不同的方法。

由于我的组织详细信息只需要提取一次,因此不需要在成员循环中,因此

我决定在Members之外分配MembershipType变量环路

这似乎已经成功了。

我想知道这是否与EF的惰性加载有关,或者类似的事情,当在一个循环中被请求时,它试图获取组织的EF实体详细信息,该循环也在获取另一个对象的详细信息。我不敢肯定说实话。

希望有人强调并解释实际原因。

我希望这能有所帮助。

相关内容

最新更新