2014-01-15 1 views
1

У меня есть ассоциация (виртуальная, lazyloaded one-to-one-or-null), и я хочу установить ее в null. Я обнаружил, что это невозможно. , если вы не используете, и затем установите для него значение null.Использование Entity Framework (Code First) для обновления/изменения объекта с нулевым соединением с нулем.

someEntity.AnotherEntity.ToString(); // Needs to be done in order to force a load since im using a service that wraps a generic repository 
someEntity.AnotherEntity = null; // Now this works because i loaded above. 

я Google вокруг много, и кажется, что хотят заряжания someEntity вариант, или добавить новое свойство к SomeEntity, который:

[ForeignKey("AnotherEntity")] // With this annotation 
int? AnotherEntity_Id // Added this property 

И затем работать с обнуляемого AnotherEntityId вместо ассоциации собственность AnotherEntity.

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

  1. Почему я не могу установить ассоциации в null и EF это понял?

  2. Что касается второго подхода, который я использую. Это хорошая практика или что-то лучше?

ответ

1

1 Почему я не могу установить ассоциации обнулить и имеют EF это понимать?

Это из-за природы вашей сущности с ленивой загрузкой. При ленивой загрузке объект не материализуется в свойстве до тех пор, пока вы не назовете метод get свойства навигации. Если вы вызываете set, убедитесь, что это поле может установить для поля поддержки свойства значение null, но EF проигнорирует его, поскольку для начала было нулевым. Поле поддержки свойства не заполняется до тех пор, пока вы не назовете get, если вы не хотите загружать.

2 Как насчет второго подхода, который я использую. Это хорошая практика или что-то лучше?

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

if (someEntity.AnotherEntity != null) // this will lazy load the instance 
    someEntity.AnotherEntity = null; // now tell EF to remove the association 

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

Кроме того, как вы отметили, если вы раскрываете свойство nullable foreign key для ассоциации, вы можете просто установить его. Поскольку он не является виртуальным, изменение его на нуль также будет иметь тот же эффект, что и ваш контекст EF, который вы хотите удалить.

+0

Спасибо @danludwig - вы объяснили это очень хорошо, и это также имеет смысл сейчас. К сожалению, этот ответ не может быть найден ни в одной документации (что я знаю). – imbageek

+1

Это неинтуитивно, и по этому поводу есть другие вопросы.Но если вы думаете об этом, вы не хотите, чтобы ваш установщик свойств попадал в db каждый раз, когда он вызывается, если свойство равно null. Это то, что он должен был бы сделать, чтобы работать, когда собственность еще не была лениво загружена. – danludwig

+0

Согласовано. Вот почему я выбираю подход № 2 и тот факт, что вы можете написать * someEntity.AnotherEntity * Теперь я рассматриваю как удобную только для чтения ассоциацию, когда истинная работа должна выполняться над свойствами Id. Это также облегчает автоматическое сопоставление класса с другим классом, когда свойства имеют одно и то же имя. – imbageek