Почему LINQ to SQL считает, что мой новый объект пуст, когда я пытаюсь добавить его в базу данных? - PullRequest
0 голосов
/ 06 октября 2010

Я пытаюсь добавить запись в таблицу базы данных, используя 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 ]

2 голосов
/ 07 октября 2010

Спасибо всем за внимание к этому вопросу.

Похоже, неправильного кода не было ни в одном коде, который я разместил здесь.Я перефразировал свой вопрос и разместил его здесь: Есть ли секрет использования LINQ to SQL для добавления записей, когда объект имеет отношения? .

Решение можно найти там!

Еще раз спасибо.

1 голос
/ 06 октября 2010

Вам не нужно прикреплять объект к таблице, поскольку объект новый. Вам просто нужно вставитьOnSubmit.

Если после удаления этой строки вы получите пустое исключение, ваш объект Stream, вероятно, пропустит обязательное поле.

0 голосов
/ 06 октября 2010

Вы пытались явно объявить 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>();
}

Поскольку только «Поток» может сбить с толку компилятор, как System.IO.Stream

Кроме того, когда вы устанавливаете точку останова на

streamTable.InsertOnSubmit(stream);

... чтобы проверить, является ли streamTable нулевым, вы проверяли его содержимое с помощью отладчика? Та часть, где написано «Расширение этого элемента, будет перечислять ...». Это важно, потому что обычно он загружается лениво, поэтому он не отправляется в БД, если не требуется транзакция.

0 голосов
/ 06 октября 2010

Может быть, streamTable равен нулю?

Редактировать

Хорошо, поэтому, основываясь на трассировке стека, я думаю, что вы можете пропустить ограничение внешнего ключа. Какие отношения имеет Stream? Можете ли вы создать новый поток в своей базе данных, используя кодированный вручную SQL, учитывая только ту информацию, которая есть в этом коде?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...