简体   繁体   English

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

[英]Entity is returning null when application is published

I have an application which is published on intranet. 我有一个在Intranet上发布的应用程序。 When I debug my application, it runs smoothly. 当我调试应用程序时,它运行平稳。 But when I published my app and my visual studio as debugger, retrieval from entity becomes null . 但是,当我发布应用程序和Visual Studio作为调试器时,从entity的检索变为null

Object reference is not set to an instance of an object. 对象引用未设置为对象的实例。

From this line (using app debugger from published version): 在这一行(使用发布版本中的应用调试器):

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

I am using MySQL database with entity framework. 我正在使用带有实体框架的MySQL数据库。 Please take note that I am working on the same PC but different version, published and not. 请注意,我在同一台PC上工作,但版本不同,但尚未发布。

Update: 更新:

This is returning null only when it is published and not when running on debugger. 仅在发布时返回null ,而在调试器上运行时则不返回null Everything is OK on debugger. 在调试器上一切正常。

This is the connection string: 这是连接字符串:

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"" 

I think it is worth mentioning that I am working on WPF. 我认为值得一提的是,我正在研究WPF。

Step Zero: More Exception Information! 步骤零:更多异常信息!

Here is a fiddle that demonstrates a quick and dirty way to get more information from your exception message. 这是一个小提琴,它演示了从异常消息中获取更多信息的快速而肮脏的方法。

Create the following method. 创建以下方法。 It recursively gathers relevant information from the Exception and all of its InnerException children. 它递归地从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();
}

Next, wrap your code in the following try-catch block. 接下来,将代码包装在以下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);
}

This will give you more than the generic NullReferenceException message. 这将为您提供比常规NullReferenceException消息更多的信息。 With more information, you might not need anymore steps. 有了更多的信息,您可能不再需要任何步骤。

Possible Extra Steps 可能的额外步骤

Step One, what is null? 第一步,什么是空值?

You already know what a NullReferenceException means. 您已经知道NullReferenceException的含义。 You're trying to access a member on a type whose value is null. 您正在尝试访问其值为null的类型的成员。 To troubleshoot, you need to determine which value is null, then you need to determine why it is null. 要进行故障排除,您需要确定哪个值为空,然后需要确定为什么为空。

Here is a Fiddle that narrows down what is null . 这里是一个缩小了是空小提琴 From that Fiddle, you can see that it's either the ctx that's null or the first item in the List<user_mstr> that is null (just pretend that a List is a DbSet ). 从该小提琴中,您可以看到是ctx为空,或者是List<user_mstr>中的第一项为空(只是假设ListDbSet )。

Here's the code from the 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();
    }
}

And here is the output. 这是输出。

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.

Step Two: what is really null? 第二步:什么是真正的null?

From step one, we know that either the ctx or the first item in the List<user_mstr> is null (where the List is just like a DbSet ). 从第一步开始,我们知道ctxList<user_mstr>的第一项为空(其中List就像DbSet )。 Now we need to narrow further. 现在我们需要进一步缩小范围。 One way to do that is to change your code to this: 一种方法是将代码更改为此:

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

If you still receive the NullReferenceException , then you know that the problematic null value is the first item in the List<user_mstr> . 如果仍然收到NullReferenceException ,则您知道有问题的null值是List<user_mstr>的第一项。 If you don't receive that exception, then you know that the problem is a null ctx . 如果未收到该异常,则说明问题是null ctx

Step Three, if the ctx is null. 第三步,如果ctx为空。

Try hard-coding your connection string. 尝试对连接字符串进行硬编码。 Here is one way to do that. 这是一种方法。

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();
}

Questions 问题

  1. What version of Entity Framework are you using? 您正在使用哪个版本的Entity Framework? The dev.mysql.com site has separate chapters about the MySQL Connector for .NET development: Chapter 9 EF 5 Support and Chapter 10 EF 6 Support . dev.mysql.com站点具有有关用于.NET开发的MySQL连接器的单独章节: 第9章EF 5支持第10章EF 6支持

  2. What version of .NET are you using? 您正在使用什么版本的.NET? Check that you're using the same .NET version for both your debug and release. 检查调试和发行版是否使用相同的.NET版本。 You'll want at least the 4.0 version. 您至少需要4.0版本。

  3. Does your release /bin contain MySql.Data.Entity.dll? 您的发行版/ bin是否包含MySql.Data.Entity.dll? If it doesn't then copy-paste it in there (and MySql.Web.dll if necessary.) There have been bugs along these lines with MySql in the Entity Framework. 如果没有,则将其复制粘贴到该位置(如果需要,则复制并粘贴到MySql.Web.dll中。)在实体框架中,与MySql一起存在这些错误。

  4. Are the release and debug builds using the same database? 版本和调试版本是否使用相同的数据库?

  5. Are you using an app.config transformation? 您是否正在使用app.config转换? This probably isn't the case, because you're using WPF and app.config transformations do not come out-of-the-box like web.config transformations do. 可能不是这种情况,因为您使用的是WPF,而app.config转换不会像web.config转换那样直接使用。

  6. Are you using a web.config transformation? 您是否正在使用web.config转换? If you're publishing as a WPF Browser Application , then a web.config file would be appropriate, and web.config transformations can change the connection string. 如果要作为WPF浏览器应用程序发布 ,则应该使用web.config文件,并且web.config转换可以更改连接字符串。

  7. Have you rebuilt (clean then build) your release? 您是否已重建(先清理然后再构建)您的发行版? You might want to go further and manually delete the /bin and /obj before your next build. 您可能想走得更远,并在下一次构建之前手动删除/bin/obj

Notes 笔记

As others have mentioned, you really need more information. 正如其他人提到的那样,您确实需要更多信息。

  • Binkes ideas of throwing the InnerException is good. Binkes抛出InnerException想法是好的。
  • Writing to a log would help. 写入日志会有所帮助。

See Also 也可以看看

MySQL with Entity Framework - what am I doing wrong? MySQL与实体框架-我在做什么错?

Entity Framework Code First + MySQL... NullReferenceException 实体框架代码优先+ MySQL ... NullReferenceException

In addition to the other good ideas. 除了其他好主意。
You say published. 你说发表。 I have seen similar issues with the way the config file gets copied. 我已经看到了复制配置文件的方式的类似问题。 Did the publish process copy the .config OR due to publish process now needs a WEB.CONFIG not app.config file ? 发布过程是否复制了.config或由于发布过程而现在需要WEB.CONFIG而不是app.config文件?

In other words the app in it new location isnt accessing the config file as you suspect and isnt finding the connection string to the original Db. 换句话说,新位置中的应用不会像您怀疑的那样访问配置文件,也不会找到与原始Db的连接字符串。

For anyone to actually answer this you need to provide some more information like a stacktrace or the actual error. 为了使任何人都能真正回答这个问题,您需要提供更多信息,例如stacktrace或实际错误。 The NullReferenceException should have an inner exception , and that is the key to know what is wrong in your published application. NullReferenceException应该具有一个内部异常 ,这是知道已发布的应用程序中有什么问题的关键。 Add a logging framework like Log4net or another logging framework to your project. Log4net之类的日志记录框架或其他日志记录框架添加到您的项目。 If you do this, you will most likely get the underlying error and stacktrace by just logging the exception. 如果执行此操作,则很可能仅记录异常即可得到基础错误和堆栈跟踪。 This will also help you alot, further down the line when unexpected errors occur. 这也将帮助您在发生意外错误时进一步深入研究。

You can always try the following to get some more information about what might be wrong: 您可以随时尝试以下操作,以获取有关可能出问题的更多信息:

Wrap your code in a try-catch and throw the InnerException 将您的代码包装在try-catch中,并引发InnerException

try { 
    vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD); 
}
catch(Exception ex) 
{ 
    throw ex.InnerException; 
}
  • Check your published connectionstring so that you don't have a transorm config that modifies your connectionstring to something unexpected. 检查您发布的连接字符串,以便您没有将连接字符串修改为意外内容的Transorm配置。

  • Make sure that your IUSR and ApplicationPoolIdentity have the right permissions. 确保您的IUSR和ApplicationPoolIdentity具有正确的权限。

  • Remove your bin and obj folders from your project, clean the solution and rebuild it. 从项目中删除binobj文件夹,清理解决方案并重建它。 Try to publish a debug version and se if it's working as expected. 尝试发布调试版本,并检查其是否按预期工作。 Publish a release version and se if it works. 发布发行版本,并检查其是否有效。

You may perform following tasks to figure out: 您可以执行以下任务来找出:

  1. To find what is happening behind the scene, verify the query translated by 要查找幕后发生的情况,请验证由
    entity framework by implemententing free profiler by how to guideline from here : http://4rapiddev.com/mysql/free-mysql-profiler-similar-to-microsoft-sql-server-profiler-logmonitor/ 实体框架,方法是通过以下指南实施免费的探查器:http: //4rapiddev.com/mysql/free-mysql-profiler-similar-to-microsoft-sql-server-profiler-logmonitor/

  2. Check the value for strUserCD variable 检查strUserCD变量的值

  3. Execute the returned query manually in MySQL 在MySQL中手动执行返回的查询

  4. If no row is being returned please change the logic how you are assinging strUserCD 如果未返回任何行,请更改逻辑方式来设置strUserCD
    variable. 变量。

  5. Publish the web application and observe any exception is being returned or not. 发布Web应用程序,观察是否返回任何异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM