为什么LINQ to SQL认为在我尝试将其添加到数据库时认为我的新对象为null?

时间:2010-10-06 16:01:23

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

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

我的控制器中填充LINQ对象的代码段是:

/* 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不为空。有些字符串为null。必需的字符串不为空(IE: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 */
}

4 个答案:

答案 0 :(得分:2)

感谢大家对此问题的关注。

看起来不正确的代码不在我发布的任何代码中。我重新提出了我的问题并在此发布:Is there a secret to using LINQ to SQL to add records when the object has relationships?

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

再次感谢。

答案 1 :(得分:1)

由于对象是新的,因此您无需将对象附加到表中。你只需要InsertOnSubmit。

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

答案 2 :(得分:0)

也许streamTable为空?

修改

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

答案 3 :(得分:0)

您是否曾尝试将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是否为null,是否用调试器检查了它的内容? 那部分里面写着“扩展这个项目将枚举......”。 这很重要,因为它通常是延迟加载,因此它不会进入数据库,除非它需要事务。