实体框架4 CRUD创建错误

时间:2011-04-03 13:02:14

标签: c# entity-framework

我的数据库中有3个相关的表。

农场----> FarmCrops< ----- Crops

我正在尝试使用一系列作物更新一个农场实体,但遇到了问题。我一直在努力工作几个小时没有成功,所以任何帮助都会非常感激。

我收到的错误是:

  

无法附加对象,因为   它已经在对象上下文中。   只有在对象时才能重新附加对象   它处于不变的状态。

我的更新逻辑如下(我为大量代码道歉。我只想尽可能清楚):

            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 个答案:

答案 0 :(得分:4)

您正在将现有的Crop个对象(来自allCrops列表)添加到新的Farm。将新实体连接到现有实体时,新实体会自动附加到上下文。因此,当您尝试第二次将Farm附加到上下文时,会出现错误。

您的代码中的Add<Farm>(farm)语句甚至不需要将Farm连接到上下文,如果您有从上下文加载的现有Farm,则它已经是附在上下文中。

您的if (isNew)声明不是必需的。实体框架跟踪对象状态本身,因此您无需设置修改后的状态。

答案 1 :(得分:3)

您不必在末尾附加“farm”对象,因为当您更改其中一个属性时,它已经被附加为已修改。尝试删除最后的else语句:

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

希望这会有所帮助:)

答案 2 :(得分:2)

问题在于您的更新方法。您无法附加Farm实例,因为您已从相同的上下文加载它,因此它已经附加,您根本不需要调用Update,因为会自动跟踪对附加对象的更改