[英]Entity is returning null when application is published
我有一個在Intranet上發布的應用程序。 當我調試應用程序時,它運行平穩。 但是,當我發布應用程序和Visual Studio作為調試器時,從entity的檢索變為null
。
對象引用未設置為對象的實例。
在這一行(使用發布版本中的應用調試器):
user_mstr vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);
我正在使用帶有實體框架的MySQL數據庫。 請注意,我在同一台PC上工作,但版本不同,但尚未發布。
更新:
僅在發布時返回null
,而在調試器上運行時則不返回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。
這是一個小提琴,它演示了從異常消息中獲取更多信息的快速而骯臟的方法。
創建以下方法。 它遞歸地從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的類型的成員。 要進行故障排除,您需要確定哪個值為空,然后需要確定為什么為空。
這里是一個縮小了的是空小提琴 。 從該小提琴中,您可以看到是ctx
為空,或者是List<user_mstr>
中的第一項為空(只是假設List
是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();
}
}
這是輸出。
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
,則您知道有問題的null值是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();
}
您正在使用哪個版本的Entity Framework? dev.mysql.com站點具有有關用於.NET開發的MySQL連接器的單獨章節: 第9章EF 5支持和第10章EF 6支持 。
您正在使用什么版本的.NET? 檢查調試和發行版是否使用相同的.NET版本。 您至少需要4.0版本。
您的發行版/ bin是否包含MySql.Data.Entity.dll? 如果沒有,則將其復制粘貼到該位置(如果需要,則復制並粘貼到MySql.Web.dll中。)在實體框架中,與MySql一起存在這些錯誤。
版本和調試版本是否使用相同的數據庫?
您是否正在使用app.config轉換? 可能不是這種情況,因為您使用的是WPF,而app.config轉換不會像web.config轉換那樣直接使用。
您是否正在使用web.config轉換? 如果要作為WPF瀏覽器應用程序發布 ,則應該使用web.config文件,並且web.config轉換可以更改連接字符串。
您是否已重建(先清理然后再構建)您的發行版? 您可能想走得更遠,並在下一次構建之前手動刪除/bin
和/obj
。
正如其他人提到的那樣,您確實需要更多信息。
InnerException
想法是好的。 除了其他好主意。
你說發表。 我已經看到了復制配置文件的方式的類似問題。 發布過程是否復制了.config或由於發布過程而現在需要WEB.CONFIG而不是app.config文件?
換句話說,新位置中的應用不會像您懷疑的那樣訪問配置文件,也不會找到與原始Db的連接字符串。
為了使任何人都能真正回答這個問題,您需要提供更多信息,例如stacktrace或實際錯誤。 NullReferenceException應該具有一個內部異常 ,這是知道已發布的應用程序中有什么問題的關鍵。 將Log4net之類的日志記錄框架或其他日志記錄框架添加到您的項目。 如果執行此操作,則很可能僅記錄異常即可得到基礎錯誤和堆棧跟蹤。 這也將幫助您在發生意外錯誤時進一步深入研究。
您可以隨時嘗試以下操作,以獲取有關可能出問題的更多信息:
將您的代碼包裝在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文件夾,清理解決方案並重建它。 嘗試發布調試版本,並檢查其是否按預期工作。 發布發行版本,並檢查其是否有效。
您可以執行以下任務來找出:
要查找幕后發生的情況,請驗證由
實體框架,方法是通過以下指南實施免費的探查器:http: //4rapiddev.com/mysql/free-mysql-profiler-similar-to-microsoft-sql-server-profiler-logmonitor/
檢查strUserCD變量的值
在MySQL中手動執行返回的查詢
如果未返回任何行,請更改邏輯方式來設置strUserCD
變量。
發布Web應用程序,觀察是否返回任何異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.