Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 发布应用程序时,实体返回null_C#_Mysql_Wpf_Entity Framework - Fatal编程技术网

C# 发布应用程序时,实体返回null

C# 发布应用程序时,实体返回null,c#,mysql,wpf,entity-framework,C#,Mysql,Wpf,Entity Framework,我有一个在内联网上发布的应用程序。调试应用程序时,它运行平稳。但当我将我的应用程序和VisualStudio作为调试器发布时,从实体中检索将变成null 对象引用未设置为对象的实例 从此行(使用已发布版本的应用程序调试器): 我使用的是带有实体框架的MySQL数据库。请注意,我在同一台电脑上工作,但版本不同,已发布,未发布 更新: 这仅在发布时返回null,而在调试器上运行时不返回。在调试器上一切正常 这是连接字符串: connectionString="metadata=res://*/Dat

我有一个在内联网上发布的应用程序。调试应用程序时,它运行平稳。但当我将我的应用程序和VisualStudio作为调试器发布时,从实体中检索将变成
null

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

从此行(使用已发布版本的应用程序调试器):

我使用的是带有实体框架的MySQL数据库。请注意,我在同一台电脑上工作,但版本不同,已发布,未发布

更新:

这仅在发布时返回
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。

要想让任何人真正回答这个问题,你需要提供更多信息,如stacktrace或实际错误。NullReferenceException应该有一个内部异常,这是了解已发布应用程序中的错误的关键。向您的项目中添加一个日志框架或另一个日志框架。如果这样做,您很可能只需要记录异常就可以得到底层错误和stacktrace。当发生意外错误时,这也将对您有很大帮助

您始终可以尝试以下操作,以获取有关可能错误的更多信息:

将代码包装在一个try catch中,并抛出InnerException

try { 
    vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD); 
}
catch(Exception ex) 
{ 
    throw ex.InnerException; 
}
  • 检查已发布的连接字符串,以便没有 transorm配置,用于修改连接字符串 出乎意料

  • 确保您的IUSR和ApplicationPoolIdentity具有正确的 权限

  • 从项目中删除bin和obj文件夹,清理 解决方案并重建它。尝试发布调试版本,如果需要,请执行se 它按预期工作。发布一个发行版版本,如果它 工作


要让任何人真正回答这个问题,您需要提供更多信息,如stacktrace或实际错误。NullReferenceException应该有一个内部异常,这是了解已发布应用程序中的错误的关键。向您的项目中添加一个日志框架或另一个日志框架。如果这样做,您很可能只需要记录异常就可以得到底层错误和stacktrace。当发生意外错误时,这也将对您有很大帮助

您始终可以尝试以下操作,以获取有关可能错误的更多信息:

将代码包装在一个try catch中,并抛出InnerException

try { 
    vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD); 
}
catch(Exception ex) 
{ 
    throw ex.InnerException; 
}
  • 检查已发布的连接字符串,以便没有 transorm配置,用于修改连接字符串 出乎意料

  • 确保您的IUSR和ApplicationPoolIdentity具有正确的 权限

  • 从项目中删除bin和obj文件夹,清理 解决方案并重建它。尝试发布调试版本,如果需要,请执行se 它按预期工作。发布一个发行版版本,如果它 工作

步骤零:更多异常信息! 从异常消息中获取更多信息的快速而肮脏的方法

创建以下方法。它递归地从
异常
及其所有
内部异常
子项收集相关信息

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块中

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
消息更多的信息。有了更多信息,您可能不再需要更多步骤

可能的额外步骤 第一步,什么是空值? 你已经知道a的意思了。您正在尝试访问值为null的类型上的成员。要进行故障排除,您需要确定哪个值为null,然后需要确定为什么为null

。从这把小提琴中,您可以看到要么是
ctx
为空,要么是
列表中的第一项为空(只要假设
列表是
DbSet

这是小提琴上的代码

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();
    }
}
第二步:什么是真正的空值? 从第一步开始,我们知道
ctx
列表中的第一项是空的(其中
列表
就像
DbSet
)。现在我们需要进一步缩小范围。一种方法是将代码更改为:

user_mstr vwUser = null;
if(ctx != null)
{
    vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);
}
如果您仍然收到
NullReferenceException
,那么您知道有问题的空值是
列表中的第一项。如果您没有收到该异常,那么您知道问题是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();
}
问题
  • 您使用的是哪个版本的Entity Framework?dev.mysql.com网站上有关于.NET开发的mysql连接器的单独章节:和

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

  • 您的发行版/bin是否包含MySql.Data.Entity.dll?如果不包含,则复制粘贴到其中(必要时粘贴到MySql.Web.dll)。实体框架中的MySql存在这些漏洞

  • 发行版和调试版是否使用相同的数据库?

  • 您使用的是app.config转换吗?可能不是这样,因为您使用的是WPF,就像web.config转换一样

  • 您正在使用web.config转换吗?如果您是作为发布,则web.config文件是合适的,并且可以更改连接
    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();
    }