【问题标题】:Why does LINQ to SQL think think that my new object is null when I try to add it to the database?为什么当我尝试将新对象添加到数据库时,LINQ to SQL 认为我的新对象为空?
【发布时间】:2011-04-21 22:18:37
【问题描述】:

我正在尝试使用 LINQ to SQL 和 ASP.NET MVC 2 向我的数据库表中添加一条记录。

我的控制器中填充 LINQ 对象的 sn-p 是这样的:

/* other code removed */
        if (ModelState.IsValid)
        {
            var stream = new Genesis.Domain.Entities.Stream();

            // Handle stream
            // Is this stream new?
            if (form.StreamID == 0)
            {
                // create new stream
                stream.StreamUrl = form.StreamUrl;
                stream.StreamName = form.StreamName;
                stream.StreamBody = form.StreamBody;
                stream.StreamTitle = form.StreamTitle;
                stream.StreamKeywords = form.StreamKeywords;
                stream.StreamDescription = form.StreamDescription;

                form.StreamID = genesisRepository.CreateStream(stream); // CreateStream() returns ID as long
            }
/* other code removed */

genesisRepository.CreateStream() 看起来像这样:

public partial class SqlGenesisRepository : IGenesisRepository
{
    public long CreateStream(Stream stream)
    {
        streamTable.InsertOnSubmit(stream);
        streamTable.Context.SubmitChanges();
        return stream.StreamID;
    }
}

genesisRepository.CreateStream() 被执行时,我得到这个错误:

更新为更准确的错误和堆栈跟踪

    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error: 


Line 13:         public long CreateStream(Stream stream)
Line 14:         {
Line 15:             streamTable.InsertOnSubmit(stream);
Line 16:             streamTable.Context.SubmitChanges();
Line 17:             return stream.StreamID;


Source File: C:\path\to\SqlGenesisRepositoryStreamPartial.cs    Line: 15 

Stack Trace: 


[NullReferenceException: Object reference not set to an instance of an object.]
   System.Data.Linq.Mapping.EntitySetDefSourceAccessor`2.GetValue(T instance) +18
   System.Data.Linq.Mapping.MetaAccessor`2.GetBoxedValue(Object instance) +47
   System.Data.Linq.StandardTrackedObject.HasDeferredLoader(MetaDataMember deferredMember) +106
   System.Data.Linq.StandardTrackedObject.get_HasDeferredLoaders() +107
   System.Data.Linq.StandardChangeTracker.Track(MetaType mt, Object obj, Dictionary`2 visited, Boolean recurse, Int32 level) +175
   System.Data.Linq.StandardChangeTracker.Track(Object obj, Boolean recurse) +83
   System.Data.Linq.StandardChangeTracker.Track(Object obj) +12
   System.Data.Linq.Table`1.InsertOnSubmit(TEntity entity) +183
   Genesis.Domain.Concrete.SqlGenesisRepository.CreateStream(Stream stream) in C:\Documents and Settings\bquakkelaar\Desktop\dropstuff\asp.net mvc\Genesis.0.02\Genesis.Domain\Concrete\SqlGenesisRepositoryStreamPartial.cs:15
   Genesis_0_02.Controllers.AdminStreamController.StreamEdit(StreamEditModel form) in C:\Documents and Settings\bquakkelaar\Desktop\dropstuff\asp.net mvc\Genesis.0.02\Genesis.0.02\Controllers\AdminStreamController.cs:107
   lambda_method(Closure , ControllerBase , Object[] ) +108
   System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +51
   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +409
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +52
   System.Web.Mvc.<>c__DisplayClassd.<InvokeActionMethodWithFilters>b__a() +127

当我在函数中设置断点时,我看到stream 不为空。一些字符串为空。必需的字符串不为空(即:streamName = "name")且 StreamID 为 0

我哪里错了?

编辑:`streamTable` 是如何被实例化的

我认为我如何实例化 streamTable 没有问题,但是看到我是如何没有想法的,这里的大多数人认为它是空的,这是实例化 streamTable 的代码。

public partial class SqlGenesisRepository : IGenesisRepository
{
    private Table<Stream> streamTable;

    public SqlGenesisRepository(string connectionString)
    {
        streamTable = (new DataContext(connectionString)).GetTable<Stream>();
    }

    public IQueryable<Stream> Streams { get { return streamTable; } }
}

并且 SqlGenesisRepository 在控制器类中被实例化,如下所示:

public class AdminStreamController : Controller
{
    private IGenesisRepository genesisRepository;

    public AdminStreamController()
    {
        //genesisRepository = new FakeGenesisRepository();
        genesisRepository = new SqlGenesisRepository(ConfigurationManager.ConnectionStrings["genesis"].ConnectionString);
    }
    /* rest of code removed for brevity */
}

【问题讨论】:

  • 错误信息表明streamTable为空——不是流
  • 有必要先附上吗? (第 31 行)
  • 我不这么认为......那条线被扔进去是为了让它工作。当该行不存在时...下一个错误。
  • 你能给我们堆栈跟踪的前几行吗?
  • @StriplingWarrior - 确定...我还从我的存储库类和控制器类中添加了更多代码来解决streamTable 问题。顺便说一句:感谢您对我的问题的关注。我不明白为什么这不起作用,感谢您的帮助。

标签: c# asp.net asp.net-mvc linq-to-sql


【解决方案1】:

也许 streamTable 为空?

编辑

好的,根据堆栈跟踪,我认为您可能缺少外键约束。 Stream 有什么关系?您是否可以使用手动编码的 SQL 在您的数据库中创建一个新的 Stream,只提供您在此代码中拥有的信息?

【讨论】:

  • 感谢您的想法。我以这种方式在另一个部分类(当然是同一类)中定义了streamTableprivate Table&lt;Stream&gt; streamTable;
  • 哦...我已经让更新功能正常工作...只是这个创建功能不知何故挂了。
  • 您的定义不会自动初始化streamTable。您是否真的检查过这个时间点的 streamTable 不为空?
  • 定义确实设置了streamTable。请注意,我发布的代码是部分定义。
  • 如果您能够使用简单的 SQL 语句创建对象,我认为您不必对 EntitySet 进行任何操作即可使其正常工作。但是,我几乎只使用实体框架,所以我不确定。不过,基于stackoverflow.com/questions/499436/…,我相信实体集应该由自动生成的构造函数实例化。所以他们不应该为空。你是在搞乱Stream 的构造函数还是什么?
【解决方案2】:

您不需要将对象附加到表格,因为对象是新的。您只需要 InsertOnSubmit。

如果删除该行后出现空异常,则您的 Stream 对象可能缺少必填字段。

【讨论】:

  • 如果我在Stream 对象中有public EntitySet&lt;T&gt; ...etc...,这是否被认为是必需的属性?
【解决方案3】:

您是否尝试过将 Stream 明确声明为 Genesis.Domain.Entities.Stream ?

如:

private Table<Genesis.Domain.Entities.Stream> streamTable;


public SqlGenesisRepository(string connectionString)
{
    streamTable = (new DataContext(connectionString)).GetTable<Genesis.Domain.Entities.Stream>();
}

因为单独的“Stream”可能会混淆编译器,如System.IO.Stream

此外,当您在

处放置断点时
streamTable.InsertOnSubmit(stream);

...要检查streamTable 是否为空,您是否使用调试器检查了它的内容? 它说“扩展此项目将枚举......”的那部分。 这很重要,因为它通常会延迟加载,因此除非需要事务,否则它不会进入数据库。

【讨论】:

  • 感谢您的建议。但是,我 100% 确定 streamTable 的定义是正确的。我会尝试你的建议,但我确信编译器理解我的意思,因为我不是课堂上的using System.IO.Stream;
  • 尝试&lt;Genesis.Domain.Entities.Stream&gt;,行为没有改变。
【解决方案4】:

感谢大家对这个问题的关注。

看起来我在此处发布的任何代码中都没有错误代码。我改写了我的问题并将其发布在这里:Is there a secret to using LINQ to SQL to add records when the object has relationships?

解决方案可以在那里找到!

再次感谢。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-16
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    相关资源
    最近更新 更多