Селфрекинг сущностей, прикрепите только саму сущность без ссылок

Используя: 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 ответа

Решение

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

Все равно спасибо за вашу работу

У вашего кода есть некоторые проблемы. Прежде всего, если вы используете 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.

Другие вопросы по тегам