Entity Framework 4 CRUD создает ошибки - PullRequest
3 голосов
/ 03 апреля 2011

У меня есть 3 связанные таблицы в моей базе данных.

Ферма ----> FarmCrops <----- Crops </p>

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

Я получаю следующую ошибку:

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

Моя логика обновления следующая (мои извинения за большой объем кода. Я просто хотел бы быть как можно более ясным)):

            bool isNew = false;
            Farm farm;

            // Insert or update logic.
            if (viewModel.Farm.FarmId.Equals(Guid.Empty))
            {
                farm = new Farm
                {
                    FarmId = Guid.NewGuid(),
                    RatingSum = 3,
                    RatingVotes = 1
                };
                isNew = true;
            }
            else
            {
                farm = this.ReadWriteSession
                       .Single<Farm>(x => x.FarmId == viewModel.Farm.FarmId);

            }

            // Edit/Add the properties.
            farm.Name = viewModel.Farm.Name;
            farm.Owner = viewModel.Farm.Owner;
            farm.Address = viewModel.Farm.Address;
            farm.City = viewModel.Farm.City;
            farm.Zip = viewModel.Farm.Zip;
            farm.WebAddress = viewModel.Farm.WebAddress;
            farm.PhoneNumber = viewModel.Farm.PhoneNumber;
            farm.Hostel = viewModel.Farm.Hostel;
            farm.Details = viewModel.Farm.Details;
            farm.Latitude = viewModel.Farm.Latitude;
            farm.Longitude = viewModel.Farm.Longitude;
            farm.Weather = viewModel.Farm.Weather;

            // Add or update the crops.
            string[] cropIds = Request.Form["crop-token-input"].Split(',');
            List<Crop> allCrops = this.ReadWriteSession.All<Crop>().ToList();

            if (!isNew)
            {
                // Remove all previous crop/farm relationships.
                farm.Crops.Clear();
            }

            // Loop through and add any crops.
            foreach (Crop crop in allCrops)
            {
                foreach (string id in cropIds)
                {
                    Guid guid = Guid.Parse(id);
                    if (crop.CropId == guid)
                    {
                        farm.Crops.Add(crop);
                    }
                }
            }

            if (isNew)
            {
                this.ReadWriteSession.Add<Farm>(farm);
            }
            else
            {
                this.ReadWriteSession.Update<Farm>(farm);
            }
            this.ReadWriteSession.CommitChanges();

Мой код обновления в ReadWriteSession достаточно прост (GetSetName<T> просто возвращает имя типа из его PropertyInfo.):

    /// <summary>
    /// Updates an instance of the specified type.
    /// </summary>
    /// <param name="item">The instance of the given type to add.</param>
    /// <typeparam name="T">The type of entity for which to provide the method.</typeparam>
    public void Update<T>(T item) where T : class, new()
    {
        this.context.AttachTo(this.GetSetName<T>(), item);
        this.context.ObjectStateManager.ChangeObjectState(item, EntityState.Modified);
    }

Ответы [ 3 ]

4 голосов
/ 03 апреля 2011

Вы добавляете существующие Crop объекты (из списка allCrops) в новый Farm. Когда вы подключаете новую сущность к существующей, новая сущность автоматически привязывается к контексту. Поэтому вы получаете сообщение об ошибке при попытке присоединить Farm к контексту во второй раз.

Инструкция Add<Farm>(farm) в вашем коде даже не нужна для подключения Farm к контексту, и если у вас есть существующий Farm, загруженный из контекста, он уже присоединен к контексту.

Все ваше утверждение if (isNew) не нужно. Платформа сущностей сама отслеживает состояние объекта, поэтому вам не нужно устанавливать измененное состояние.

3 голосов
/ 03 апреля 2011

вам не нужно прикреплять объект «ферма» в конце, потому что он уже прикреплен как измененный при изменении одного из его свойств.попробуйте удалить оператор else в конце:

if (isNew)
{
   this.ReadWriteSession.Add<Farm>(farm);
}

Надеюсь, это поможет:)

2 голосов
/ 03 апреля 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...