【问题标题】:"Object reference not set to an instance of an object" on Retrieving data检索数据上的“对象引用未设置为对象的实例”
【发布时间】:2020-09-02 15:31:22
【问题描述】:

我试图从 SQL 数据库中检索数据。我正在使用 Entity Framework 核心。它从数据库中检索所需的数据。我可以在调试时看到数据,但数据没有分配给 var 类型的变量。仅供参考,变量 type 的值是 0 并且它基本上是一个 enum,我将其类型转换为 int。下面是代码

public async Task<string> GetMailTemplateByType(Models.TemplateTypes type)
    {
        var mailTemplate = await _userDbContext.MailTemplates.FirstOrDefaultAsync(mt => mt.TemplateType==((int)type));
        return mailTemplate.MailHtml;
    }

这是定义:

var HtmlTemplate = await _coreDataManager.GetMailTemplateByType(TemplateTypes.Activation);

当使用 try catch 进行调试时,它会显示

对象引用未设置为对象的实例

这里有什么问题?

【问题讨论】:

  • 您可以从检查 mailTemplate 的值开始。
  • 除非您的 ((int)type) 在上面的示例中等于 0,否则它不会返回您在调试器中显示的邮件模板
  • 您确定您收到任何数据吗?如果 linq 没有找到感兴趣的数据,它会以 null 响应,如果 string 为 null .. 它为 null。您应该检查 mailTemplate 是否为 null (try{ ...}catch(NullReferenceException err){ Console.Writeline(err.Message);} 如果它显示相同,则您刚刚捕获了 null 异常,这确实意味着您试图找到不存在的东西。
  • 是的,mailTemplate 为空,但我可以在第一个屏幕截图中看到我的数据库中的数据

标签: c# linq entity-framework-core


【解决方案1】:

我们可以从您的代码中看到您收到以下邮件模板对象: ID = {aeced541-7003-437e-8f77-4605766fb62c}; MailHtml = "您好,
非常感谢您的注册。这里是确认链接以继续下一步......"; 模板类型 = 0;

这里你传递了一些我们不知道的 TemplateType 值

public async Task<string> GetMailTemplateByType(Models.TemplateTypes type)
{

在这里,您将该类型值与我们在调试器窗口中看到的 MailTemplate 对象中的 TemplateType 属性进行比较

var mailTemplate = await _userDbContext.MailTemplates.FirstOrDefaultAsync(mt => mt.TemplateType==((int)type));

但是如果type不为0,它不会返回MailTemplate对象,因为我们在调试器窗口中看到的MailTemplate对象的TemplateType值为0,因此FirstOrDefaultAsync会返回一个空值,见"fault returns NullReferenceException if no match is found"

【讨论】:

  • 您是否可以提供 MailTemplate 对象和 TemplateTypes 枚举的定义,以便更好地理解比较可能失败的原因?
  • @NishanthPrabhakaran 根据您的枚举定义,您只有一个枚举值 Activation = 1,如果不是 0,您怎么能将值 0 传递给 GetMailTemplateByType(Models.TemplateTypes type) TemplateTypes 的有效值
  • 您需要在枚举中将 Activation 更改为 0 或将数据库中的 TemplateType 更新为 1 以便它们匹配
【解决方案2】:
public async Task<string> GetMailTemplateByType(Models.TemplateTypes type)
{
  var mailTemplate = /*your expression from screenshot*/.FirstOrDefault();
  if(mailTemplate = null)
    throw new NullReferenceException();
  return mailTemplate;
}

..........................
try
{
  GetMailTemplateByType(TemplateTypesVariable);
}
catch(NullReferenceException err)
{
   Console.WriteLine("template does not exist");
}

您似乎正在尝试接收不存在的数据。

【讨论】:

  • 我可以看到填充的数据,如您在第一个屏幕截图中所见。 FirstOrDefaultAsync() 中会有什么问题。
  • public async Task&lt;string&gt; 但我不明白,但你想从这个方法返回什么?自己的类型,还是字符串类型?我知道如果它的 Task 你期望字符串,所以它可以修复这样的异常,你需要使用它来确定你想要返回的内容。你能告诉我你的实体吗?
【解决方案3】:

为什么还要选择整个对象? ef-core 就像 sql,选择你需要的(在你的情况下只需做一个

var mailTemplate = await _userDbContext.MailTemplates.Where(mt => mt.TemplateType==((int)type)).Select(x => x.MailHtml).FirstOrDefaultAsync();

但这仍然行不通,因为您的实体说 TemplateType 为 0(并且您的枚举以 1 开头)。猜你保存错了

想写这篇评论,但我刚刚创建了这个帐户

【讨论】:

  • 我得到了答复,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多