我正在尝试这么真实,非常简单,但实体框架似乎有很多方法可以做到这一点,但似乎都没有。
我有一个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实体。我想要做的应该是非常简单,我不知道为什么不是。
答案 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();
第一行主要是不需要的,因为如果你将状态设置为修改,第二行将会附加实体,但是我希望将它保留在代码中以使其显而易见。