Linq to SQL Update - исключение NullReferenceException при обновлении после отсоединения - PullRequest
1 голос
/ 21 мая 2011

В настоящее время я не могу понять, почему мой метод обновления в моем хранилище для объекта стиля создает исключение NullReferenceException в моем уровне модели домена Linq to SQL. Кажется, проблема в том, что свойство EntitySet<Product> Product обновляемого объекта Style становится нулевым после необходимого использования метода Detach. Фактическое исключение выдается в приложении до подачи изменений.

Мое обновление предназначено только для таблицы стилей, ссылка на продукт на самом деле не должна в нее входить, но связь отображается в коде, сгенерированном SQLMetal, который является важной частью моей разработки приложения.

Если я удаляю отношение внешнего ключа, воссоздаю класс отображения и соответствующим образом корректирую код, проблема исчезает. Тем не менее, я хотел бы сохранить отношения с иностранными ключами, если это возможно.

Я попытаюсь лучше объяснить настройку:

Отношения в базе данных сервера SQL примерно такие, с таблицей Product, ссылающейся на таблицу стилей:

enter image description here

Класс отображения сущностей создается с помощью SQLMetal, насколько я знаю, в способе его генерации нет ничего необычного.

Метод обновления:

public Style Update(Style style)
    {
        using (var dc = new ProjectERPDataContext(Config.ConnectionStringERPDB))
        {
            style.Detach();

            dc.Style.Attach(style);
            dc.Refresh(RefreshMode.KeepCurrentValues, style);
            dc.SubmitChanges();

            return style;
        }
    }

Метод отсоединения хранится в частичном классе:

Метод отсоединения существует, потому что без него выдается исключение: «Предпринята попытка присоединить или добавить объект, который не является новым, возможно, был загружен из другого DataContext. Это не поддерживается».

public partial class Style
{
    public void DetachEntityRefs()
    {
        this._Product = default(EntitySet<Product>);
    }
}

Класс сущности начинается как:

[Table(Name="dbo.Style")]
public partial class Style : INotifyPropertyChanging, INotifyPropertyChanged
{

    private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);

    private int _ID;

    private string _Name;

    private EntitySet<Product> _Product;

Таким образом, вы можете точно видеть, где выбрасывается исключение:

enter image description here

Полная трассировка стека:

    System.NullReferenceException : Object reference not set to an instance of an object.
at System.Data.Linq.Mapping.EntitySetDefSourceAccessor`2.GetValue(T instance)
at System.Data.Linq.Mapping.MetaAccessor`2.GetBoxedValue(Object instance)
at System.Data.Linq.ChangeTracker.StandardChangeTracker.StandardTrackedObject.HasDeferredLoader(MetaDataMember deferredMember)
at System.Data.Linq.ChangeTracker.StandardChangeTracker.StandardTrackedObject.get_HasDeferredLoaders()
at System.Data.Linq.ChangeTracker.StandardChangeTracker.Track(MetaType mt, Object obj, Dictionary`2 visited, Boolean recurse, Int32 level)
at System.Data.Linq.ChangeTracker.StandardChangeTracker.Track(Object obj, Boolean recurse)
at System.Data.Linq.Table`1.Attach(TEntity entity, Boolean asModified)
at ProjectERP.DomainModel.Repositories.SQLStyleRepo.Update(Style style) in SQLStyleRepo.cs: line 45
at ProjectERP.UnitTests.DomainModel.SQLStyleRepoTests.Test_can_update_style() in SQLStyleRepoTests.cs: line 67 

1 Ответ

3 голосов
/ 21 мая 2011

Бьюсь об заклад, причина в том, что эта бомба замедленного действия, которую вы заложили здесь:

this._Product = default(EntitySet<Product>);

default(EntitySet<Product>) - это null. Попробуйте установить его на что-то :

this._Product = new EntitySet<Product>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...