Селфрекинг сущностей, прикрепите только саму сущность без ссылок - PullRequest
0 голосов
/ 20 марта 2012

с использованием: SQL Server 2008 R2, Entityframework 4.3.1

мой сценарий: я считываю свои объекты из базы данных на стороне обслуживания.Я использую шаблон T4 "Селфрекинг-сущности" для создания объектов из объектного контекста.Эти объекты доставляются клиенту, где ими манипулируют, и отправляют обратно в службу.

Посредством самообследования я могу видеть, какие свойства были изменены на стороне клиента.

Мой метод обновления сущности выглядит следующим образом:

using ( var transaction = new TransactionScope() )
            {
                var connection = this.ConnectionManager.GetConnectionstring( AcademyOne.Models.Connection.A1Databases.A1VerwaltungEntity );

                using ( var context = new istis.AcademyOne.Models.Models.A1Verwaltung.VerwaltungModelsContext( connection.Connectionstring ) )
                {
                    foreach ( var seminar in seminare )
                    {
                        context.Seminar.Attach( seminar );
                        context.ObjectStateManager.ChangeObjectState( seminar, StateValueConverter.GetEquivalentEntityState( seminar.ChangeTracker.State ) );

                    }
                    context.SaveChanges( SaveOptions.DetectChangesBeforeSave );
                }             

                transaction.Complete();
            }

Моя проблема.Субъект "Семинар" имеет ссылку на "Дозент".Может быть несколько семинаров, имеющих ссылку на один и тот же объект Dozentobject.Поэтому, когда я присоединяю оба семинара с одной и той же ссылкой, я получаю следующее исключение:

Объект с таким же ключом уже существует в ObjectStateManager.ObjectStateManager не может отслеживать несколько объектов с одним и тем же ключом

Есть идеи, как решить эту проблему?Есть ли возможность прикрепить только простой объект без ссылки, но включая идентификатор ForeignKey?Любые другие подходы, которые я могу попробовать?

Ответы [ 2 ]

0 голосов
/ 20 марта 2012

Решил мою проблему с помощью своего рода грязного обходного пути. Я вставляю / обновляю теперь каждый элемент по-своему, и теперь он работает. Надеялся на пакетное обновление, но это не представляется возможным.

Спасибо за вашу работу в любом случае

0 голосов
/ 20 марта 2012

Ваш код имеет некоторые проблемы.Прежде всего, если вы используете Self Tracking Entities, вам не нужно менять состояние службы отслеживания изменений в службе.Поскольку сущности с самопроверкой имеют свое собственное состояние, если вы попытаетесь сохранить какой-либо объект, контекст выполнит соответствующее действие в соответствии с состоянием отслеживания объекта.Таким образом, только присоединение обновленного объекта и вызов сохраненных изменений достаточно для сохранения объекта.

using ( var transaction = new TransactionScope() )
        {
            var connection = this.ConnectionManager.GetConnectionstring( AcademyOne.Models.Connection.A1Databases.A1VerwaltungEntity );

            using ( var context = new istis.AcademyOne.Models.Models.A1Verwaltung.VerwaltungModelsContext( connection.Connectionstring ) )
            {
                foreach ( var seminar in seminare )
                {
                    //The following line shall be commented out
                    //context.Seminar.Attach( seminar );

                    context.Seminar.ApplyChanges( seminar );

                    //The following line shall be commented out.
                    //context.ObjectStateManager.ChangeObjectState( seminar, StateValueConverter.GetEquivalentEntityState( seminar.ChangeTracker.State ) );

                }
                context.SaveChanges( SaveOptions.DetectChangesBeforeSave );
            }             

            transaction.Complete();
        }

Во-вторых, я думаю, что эта проблема возникает из-за того, что состояние сущности Dozent создано.Таким образом, когда вы вызываете метод присоединения для каждой обновленной сущности Семинара, к контексту объекта присоединяется новая сущность Dozent (фактически разные объекты с одинаковым идентификатором);что приводит к нарушению первичного ключа.

Чтобы решить эту проблему, вместо отправки списка семинаров отправьте объект, имеющий отношение один-ко-многим с объектами семинара (конечно, если у вас есть такой объект).

Или, если у вас нет родительской сущности, попробуйте установить значения внешнего ключа сущностей семинара, не устанавливая связанное свойство навигации Dozent.Сначала убедитесь, что свойства внешнего ключа существуют в файле модели EDMX.

...