C# 发布应用程序时,实体返回null
我有一个在内联网上发布的应用程序。调试应用程序时,它运行平稳。但当我将我的应用程序和VisualStudio作为调试器发布时,从实体中检索将变成C# 发布应用程序时,实体返回null,c#,mysql,wpf,entity-framework,C#,Mysql,Wpf,Entity Framework,我有一个在内联网上发布的应用程序。调试应用程序时,它运行平稳。但当我将我的应用程序和VisualStudio作为调试器发布时,从实体中检索将变成null 对象引用未设置为对象的实例 从此行(使用已发布版本的应用程序调试器): 我使用的是带有实体框架的MySQL数据库。请注意,我在同一台电脑上工作,但版本不同,已发布,未发布 更新: 这仅在发布时返回null,而在调试器上运行时不返回。在调试器上一切正常 这是连接字符串: connectionString="metadata=res://*/Dat
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 它按预期工作。发布一个发行版版本,如果它 工作
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
,那么您知道有问题的空值是列表中的第一项。如果您没有收到该异常,那么您知道问题是nullctx
第三步,如果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();
}