【问题标题】:Entity Framework POCO Update Entity?实体框架 POCO 更新实体?
【发布时间】:2012-03-22 10:06:29
【问题描述】:

我正在尝试做一些非常非常简单的事情,但是 Entity Framework 似乎有很多方法可以做到这一点,但似乎都不起作用。

我有一个从数据库中读取的 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 的上下文的情况下更新我的产品实体。我正在尝试做的事情应该非常简单,我不知道为什么不是。

【问题讨论】:

    标签: entity-framework entity poco objectcontext


    【解决方案1】:

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

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

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

    第一行基本上是不需要的,因为如果您将实体的状态设置为已修改,第二行无论如何都会附加实体,但我喜欢将其保留在代码中以使这一点显而易见。

    【讨论】:

    • 谢谢拉迪斯拉夫。那已经解决了。实体框架有很多变体。你知道有什么好的资源可以准确地列出有哪些变体,它们有何不同以及如何使用它们。最初 EF 是微软的好主意之一,但从那以后他们似乎把它搞砸了。
    • 只有两种变体。查看这两本书了解 DbContext API:Programming EF: Code FirstProgramming EF: DbContext
    猜你喜欢
    • 1970-01-01
    • 2011-08-21
    • 2011-08-11
    • 1970-01-01
    • 1970-01-01
    • 2012-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多