实体框架POCO更新实体?

时间:2012-03-04 19:31:32

标签: entity-framework entity poco objectcontext

我正在尝试这么真实,非常简单,但实体框架似乎有很多方法可以做到这一点,但似乎都没有。

我有一个POCO类,我已从数据库中读取,我想更新数据库中对该类的更改。这就是我想做的一切。

以下是我的尝试: -

1)我的POCO课程: -

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Web.Mvc; // Needs project reference to System.Web.Mvc 3.0.0.0
using System.ComponentModel.DataAnnotations; // Needs project reference to System.ComponentModel.DataAnnotations 4.0.0.0

namespace Trust.Domain.Entities
{
    public class Product
    {
        [HiddenInput(DisplayValue=false)]
        public Int32 ProductID { get; set; }
        [Required(ErrorMessage = "Please enter a product name.")]
        public String Name { get; set; }
        [DataType(DataType.MultilineText)]
        public String Description { get; set; }
        public Decimal? PriceGuide { get; set; }
        public Decimal? PriceSold { get; set; }
        public Int32? HeightCM { get; set; }
        public Int32? WidthCM { get; set; }
        public Int32? DepthCM { get; set; }
        [Required(ErrorMessage = "Please enter a list of keywords. Seperate each with a comma.")]
        public String Keywords { get; set; }
        public String SKU { get; set; }
        public Int32 ProductStateID { get; set; }
    }
}

2)我更新此POCO类实例的上下文: -

using System; using System.Collections.Generic; using System.Linq;
using System.Text;

using Trust.Domain.Entities; using Trust.Domain.Abstract;

namespace Trust.Domain.Contrete {
    public class EFProductRepository : IProductRepository
    {
        private EFDbContext context = new EFDbContext();

        public IQueryable<Product> Products
        {
            get { return context.Products; }
        }

        public Product GetProduct(int productID)
        {
            Product product = context.Products.Where(p => p.ProductID == productID).FirstOrDefault();
            return product;
        }

        public void SaveProduct(Product product)
        {
            if (product.ProductID == 0)
            {
                context.Products.Add(product);
                context.SaveChanges();
            }
            else
            {
                //context.AttachTo("Product", product); 
                //var contactEntry = Context.ObjectStateManager.GetObjectStateEntry(product); 
                //contactEntry.ChangeState(EntityState.Modified); 
                //_context.SaveChanges();

                //var findProduct = GetProduct(product.ProductID); 
                //context.ApplyCurrentValues("Product", product); 
                //context.SaveChanges(); 

                context.Products.Attach(product);
                context.SaveChanges();

            }
        }

        public void DeleteProduct(Product product)
        {
            context.Products.Remove(product);
            context.SaveChanges();
        }
    }
}

3)EFDbContext定义为: -

using System; using System.Collections.Generic; using System.Linq;
using System.Text;

using System.Data.Entity; // Needs Entity Framework 4.1 project
reference. using System.Data.Entity.ModelConfiguration.Conventions;

using Trust.Domain.Entities;

namespace Trust.Domain.Contrete {
    public class EFDbContext : DbContext
    {
        #region " Overrides "

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

            base.OnModelCreating(modelBuilder);
        }

        #endregion

        #region " Entities "

        public DbSet<Product> Products { get; set; }

        #endregion
    }
}

在SaveProduct例程中,我检查ProductID是否不为零。如果它不为零,那么我尝试更新数据库中的实体。在这段代码中,我提出了三种我在周围和周围找到的方法。前两个是注释掉的,因为他们甚至没有编译,因为他们使用的成员不存在!第三个看起来很好,运行并且根本不会更改数据库。

实体框架是一个变化大,复杂且过度设计的技术,所以有很多方法可以做任何事情。有人可以告诉我如何在给定POCO类型和我创建的基于EFDbContext的上下文的情况下更新我的Product实体。我想要做的应该是非常简单,我不知道为什么不是。

1 个答案:

答案 0 :(得分:2)

这些成员不存在的原因是EF有两种不同的API:旧的ObjectContext API和更新的DbContext API。前两个解决方案使用的是ObjectContext API,但您使用的是DbContext API。

问题是附加实体只会附加它,但它会将其标记为未更改,因此您需要将其标记为已修改,以便EF知道该实体必须保存:

context.Products.Attach(product);
context.Entry(product).State = EntityState.Modified;
context.SaveChanges();

第一行主要是不需要的,因为如果你将状态设置为修改,第二行将会附加实体,但是我希望将它保留在代码中以使其显而易见。