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

时间:2015-02-07 06:57:47

标签: c# mysql wpf entity-framework

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

  

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

从这一行(使用已发布版本的app调试器):

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

我正在使用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"" 。调试器上一切正常。

这是连接字符串:

{{1}}

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

4 个答案:

答案 0 :(得分:9)

第零步:更多异常信息!

Here is a fiddle that demonstrates一种从您的异常消息中获取更多信息的快捷方式。

创建以下方法。它以递归方式收集Exception及其所有InnerException个孩子的相关信息。

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

可能的额外步骤

第一步,什么是空?

您已经知道NullReferenceException的含义。您尝试访问值为null的类型的成员。要进行故障排除,您需要确定哪个值为null,然后您需要确定它为空的原因。

Here is a Fiddle that narrows down what is null。从那个小提琴开始,你可以看到ctx为空的List<user_mstr>List中的第一个为空的项目(只是假装DbSetusing 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.

这是输出。

ctx

第二步:什么是真的?

从第一步开始,我们知道List<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>,那么您就知道有问题的空值是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(); } 为空。

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

/bin

问题

  1. 您使用的是什么版本的Entity Framework? dev.mysql.com网站有关于MySQL Connector for .NET开发的单独章节:Chapter 9 EF 5 Support和{{3 }}

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

  3. 你的发布/ bin是否包含MySql.Data.Entity.dll?如果它没有,那么将其复制粘贴到那里(如果需要,还有MySql.Web.dll) 。)实体框架中的MySql存在这些问题。

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

  5. 您使用的是app.config转换吗?这可能不是这样,因为您正在使用WPF和Chapter 10 EF 6 Support之类的web.config转型呢。

  6. 您使用的是web.config转换吗?如果您要作为app.config transformations do not come out-of-the-box发布,那么web.config文件将是合适的,{{ 3}}可以更改连接字符串。

  7. 您是否重建(清理然后构建)您的版本?您可能希望在下次构建之前进一步手动删除/objInnerException

  8. 注释

    正如其他人所说,你真的需要更多信息。

    • Binkes抛出{{1}}的想法很好。
    • 写日志会有所帮助。

    另请参阅

    WPF Browser Application

    web.config transformations

答案 1 :(得分:2)

除了其他好主意外 你说发表了。我看到配置文件被复制的方式有类似的问题。 由于发布过程,发布过程是否复制.config OR现在需要WEB.CONFIG而不是app.config文件?

换句话说,新位置的应用程序无法访问您怀疑的配置文件,并且找不到原始Db的连接字符串。

答案 2 :(得分:1)

对于任何人实际回答此问题,您需要提供更多信息,例如堆栈跟踪或实际错误。 NullReferenceException 应该有内部异常,这是了解已发布应用程序中出错的关键。将Log4net或其他日志框架等日志框架添加到项目中。如果这样做,您很可能只需记录异常就可以获得基础错误和堆栈跟踪。这也可以帮助您在发生意外错误时进一步发挥作用。

您可以随时尝试以下方法,以获取有关可能出现的错误的更多信息:

将代码包装在 try-catch 中并抛出InnerException

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

  • 确保您的IUSR和ApplicationPoolIdentity有权使用 权限。

  • 从项目中删除 bin obj 文件夹,清理 解决方案并重建它。尝试发布调试版本和se if 它按预期工作。发布发布版本,如果是,则发布 作品。

答案 3 :(得分:1)

您可以执行以下任务来确定:

  1. 要查找场景背后发生的情况,请验证由翻译翻译的查询 实体框架通过如何从这里指导实施免费分析器: http://4rapiddev.com/mysql/free-mysql-profiler-similar-to-microsoft-sql-server-profiler-logmonitor/

  2. 检查strUserCD变量的值

  3. 在MySQL

  4. 中手动执行返回的查询
  5. 如果没有返回行,请更改逻辑如何协助strUserCD
    变量

  6. 发布Web应用程序并观察是否返回任何异常。