c# - 发布应用程序时实体返回 null

标签 c# mysql wpf entity-framework

我有一个在 Intranet 上发布的应用程序。当我调试我的应用程序时,它运行顺利。但是,当我将我的应用程序和我的 visual studio 作为调试器发布时,实体检索变为 null

Object reference is not set to an instance of an object.

从这一行开始(使用已发布版本的应用程序调试器):

user_mstr vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);

我正在使用带有 Entity Framework 的 MySQL 数据库。请注意,我在同一台 PC 上工作,但版本不同,发布的和未发布的。

更新:

这仅在发布时返回 null,在调试器上运行时不返回。在调试器上一切正常。

这是连接字符串:

connectionString="metadata=res://*/DataAccess.entityName.csdl|res://*/DataAccess.entityName.ssdl|res://*/DataAccess.entityName.msl;provider=MySql.Data.MySqlClient;provider connection string="server=servername;user id=username;password=password;persistsecurityinfo=True;Convert Zero Datetime=True;database=default_db"" 

我认为值得一提的是我正在研究 WPF。

最佳答案

第零步:更多异常信息!

Here is a fiddle that demonstrates从异常消息中获取更多信息的快速而肮脏的方法。

创建以下方法。它递归地从 Exception 中收集相关信息。及其所有 InnerException children 。

public string ExceptionDetails(StringBuilder b, Exception e)
{
    if (e != null)
    {
        b.AppendLine("\n\n-----");
        b.AppendLine("Data:".PadRight(20) + e.Data);
        b.AppendLine("Message:".PadRight(20) + e.Message);
        b.AppendLine("StackTrace:".PadRight(17) + e.StackTrace);
        b.AppendLine("TargetSite:".PadRight(20) + e.TargetSite.ToString());
        b.AppendLine("-----");
        ExceptionDetails(b, e.InnerException);
    }

    return b.ToString();
}

接下来,将您的代码包装在以下 try-catch block 中。

try
{
    user_mstr vwUser = 
        ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);    
}
catch (Exception e)
{
    var builder = new StringBuilder();
    var details = ExceptionDetails(builder, e);
    throw new Exception(details);
}

这将给您带来比通用 NullReferenceException 更多的信息信息。有了更多信息,您可能不再需要其他步骤。

可能的额外步骤

第一步,什么是null?

您已经知道什么是 NullReferenceException方法。您正在尝试访问值为 null 的类型的成员。要排除故障,您需要确定哪个值为空,然后您需要确定它为什么为空。

Here is a Fiddle that narrows down what is null .从那个 fiddle ,你可以看到它是 ctx那是 null 或 List<user_mstr> 中的第一项那是空的(假装 ListDbSet )。

这是来自 Fiddle 的代码。

using System;
using System.Collections.Generic;
using System.Linq;

public class user_mstr
{
    public string user_cd;
}

public class FakeContext
{
    public List<user_mstr> user_mstr;
}

public class Program
{
    private static string strUserCD = "foo";

    private static void FirstUserAsNull()
    {
        try
        {
            Console.WriteLine("FirstUserAsNull");
            FakeContext ctx = new FakeContext();
            ctx.user_mstr = new List<user_mstr>() { null, new user_mstr(), new user_mstr() };
            user_mstr vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);
        }
        catch (NullReferenceException e)
        {
            Console.WriteLine(e.Message);
        }
        catch (ArgumentNullException e)
        {
            Console.WriteLine(e.Message);
            Console.WriteLine();
        }
    }

    private static void UserListAsNull()
    {
        try
        {
            Console.WriteLine("UserListAsNull");
            FakeContext ctx = new FakeContext();
            ctx.user_mstr = null;
            user_mstr vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);
        }
        catch (NullReferenceException e)
        {
            Console.WriteLine(e.Message);
        }
        catch (ArgumentNullException e)
        {
            Console.WriteLine(e.Message);
            Console.WriteLine();
        }
    }

    private static void CtxAsNull()
    {
        try
        {
            Console.WriteLine("CtxAsNull");
            FakeContext ctx = null;
            user_mstr vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);
        }
        catch (NullReferenceException e)
        {
            Console.WriteLine(e.Message);
            Console.WriteLine();
        }
    }

    public static void Main()
    {
        CtxAsNull();
        UserListAsNull();
        FirstUserAsNull();
    }
}

这是输出。

CtxAsNull
Object reference not set to an instance of an object.

UserListAsNull
Value cannot be null.
Parameter name: source

FirstUserAsNull
Object reference not set to an instance of an object.

第二步:什么是真正的 null?

从第一步,我们知道 ctxList<user_mstr> 中的第一项为空(其中 List 就像 DbSet )。现在我们需要进一步缩小范围。一种方法是将您的代码更改为:

user_mstr vwUser = null;
if(ctx != null)
{
    vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);
}

如果您仍然收到 NullReferenceException ,那么您就知道有问题的空值是 List<user_mstr> 中的第一项。 .如果您没有收到该异常,那么您就知道问题是 null ctx .

第三步,如果ctx为空。

尝试对连接字符串进行硬编码。这是一种方法。

var providerName = "MySql.Data.MySqlClient";

var builder = new StringBuilder();
builder.Append("server=servername;");
builder.Append("user id=username;");
builder.Append("password=password;");
builder.Append("persistsecurityinfo=True;");
builder.Append("Convert Zero Datetime=True;");
builder.Append("database=default_db");

var providerString = builder.ToString();

var entityBuilder = new EntityConnectionStringBuilder();
entityBuilder.Provider = providerName;
entityBuilder.ProviderConnectionString = providerString;

entityBuilder.Metadata = @"res://*/DataAccess.entityName.csdl|
                           res://*/DataAccess.entityName.ssdl|
                           res://*/DataAccess.entityName.msl";

using (var conn = new EntityConnection(entityBuilder.ToString()))
{
    conn.Open();

    // do something

    conn.Close();
}

问题

  1. 您使用的是哪个版本的 Entity Framework?dev.mysql.com 站点有单独的章节介绍用于 .NET 开发的 MySQL 连接器:Chapter 9 EF 5 SupportChapter 10 EF 6 Support .

  2. 您使用的是哪个版本的 .NET?检查您使用的调试和发布版本是否相同。您至少需要 4.0 版本。

  3. 您的版本/bin 是否包含 MySql.Data.Entity.dll?如果没有,则将其复制粘贴到其中(如果需要,还可以复制粘贴 MySql.Web.dll。) Entity Framework 中的 MySql 在这些方面存在错误。

  4. 发布版本和调试版本是否使用相同的数据库?

  5. 您是否在使用 app.config 转换?情况可能并非如此,因为您使用的是 WPF 和 app.config transformations do not come out-of-the-box就像 web.config 转换一样。

  6. 您是否使用 web.config 转换?如果您发布为 WPF Browser Application ,那么一个 web.config 文件将是合适的,并且 web.config transformations可以更改连接字符串。

  7. 您是否重建(清理然后构建)您的版本?您可能想要更进一步并手动删除 /bin/obj在你的下一次构建之前。

注意事项

正如其他人所提到的,您确实需要更多信息。

  • Binkes 关于抛出 InnerException 的想法很好。
  • 写入日志会有所帮助。

另见

MySQL with Entity Framework - what am I doing wrong?

Entity Framework Code First + MySQL... NullReferenceException

关于c# - 发布应用程序时实体返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28379514/

相关文章:

c# - 如何在不使用 "new"关键字的情况下启动一个类?

c# - ComboBox 项目的自定义项目模板

mysql - 同时向两个表添加数据

c# - 我可以从同一列中选择多个值吗

C# 在任务中更新 UI

c# - 如何在开始菜单中为 ClickOnce 应用程序创建卸载链接

c# - 在按钮单击事件中增加图像按钮的亮度

mysql - 无法使用 JSON_EXTRACT 在 MySQL 中提取具有特殊字符的键

c# - 通过匿名委托(delegate)取消订阅事件

c# - 实现行级分析