Entity Framework POCO Обновить сущность? - PullRequest
1 голос
/ 04 марта 2012

Я пытаюсь сделать что-то действительно очень простое, но у 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 нулю. Если это не ноль, то я пытаюсь обновить сущность в базе данных. В этом коде я представляю три способа сделать это, которые я нашел вокруг. Первые два являются комментариями, потому что они даже не компилируются, потому что используемые ими члены не существуют! Третий выглядит хорошо, работает и не вносит никаких изменений в базу данных.

Entity Framework - это очень крупная, сложная и сложная технология, поэтому существует множество способов сделать что-либо. Может кто-нибудь сказать мне, как обновить сущности моего Продукта, учитывая тип POCO и контекст, основанный на EFDbContext, который я создал. То, что я пытаюсь сделать, должно быть потрясающе простым, я не знаю, почему это не так.

1 Ответ

2 голосов
/ 05 марта 2012

Причина, по которой эти члены не существуют, заключается в том, что для EF существует два разных API: более старый API ObjectContext и более новый API DbContext.Эти первые два решения используют ObjectContext API, но вы используете DbContext API.

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

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

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

...