В настоящее время я не могу понять, почему мой метод обновления в моем хранилище для объекта стиля создает исключение NullReferenceException в моем уровне модели домена Linq to SQL. Кажется, проблема в том, что свойство EntitySet<Product> Product
обновляемого объекта Style становится нулевым после необходимого использования метода Detach. Фактическое исключение выдается в приложении до подачи изменений.
Мое обновление предназначено только для таблицы стилей, ссылка на продукт на самом деле не должна в нее входить, но связь отображается в коде, сгенерированном SQLMetal, который является важной частью моей разработки приложения.
Если я удаляю отношение внешнего ключа, воссоздаю класс отображения и соответствующим образом корректирую код, проблема исчезает. Тем не менее, я хотел бы сохранить отношения с иностранными ключами, если это возможно.
Я попытаюсь лучше объяснить настройку:
Отношения в базе данных сервера SQL примерно такие, с таблицей Product, ссылающейся на таблицу стилей:
Класс отображения сущностей создается с помощью 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;
Таким образом, вы можете точно видеть, где выбрасывается исключение:
Полная трассировка стека:
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