决定插入或更新实体框架

本文关键字:实体 框架 更新 插入 决定 | 更新日期: 2023-09-27 18:01:15

我编写这个函数是为了使用POCO类将数据保存到EF4:

public void Guardar(Pedidos myPedido)
    {
        using (var context = new OhmioEntities())
        {
            if (myPedido.ID_Pedido == 0)
            {
                context.Pedidos.AddObject(myPedido);
            }
            else
            {
                context.Pedidos.Attach(myPedido);
                context.ObjectStateManager.ChangeObjectState(myPedido, System.Data.EntityState.Modified);                                        
            }
            context.SaveChanges();
        }
    }

现在我想在基类上用一种通用的方式来写这篇文章。有没有一种方法可以决定我是否需要在不使用ID的情况下执行UPDATE或INSERT?(本例中为ID_Pedido(,因为键字段上的名称在每个对象类型上都会发生变化。代码的其余部分是通用的。我正在训练,以知道我是否需要使用AddObject(新(或Attach(现有(。谢谢!

决定插入或更新实体框架

查看方法InsertOrUpdate!您可以使此存储库更通用;例如,您可以创建一个Entity基类,并在泛型方法中使用它。

public class Employee
{
    public int Id { get; set; }
    public string FullName { get; set; }
}


Now using this we will have a simple context class
public class HRContext : DbContext
{        
    public DbSet<DomainClasses.Employee> Employees { get; set; }
}

After that, define the repository interface IEmployeeRepository 

public interface IEmployeeRepository : IDisposable
{
    IQueryable<Employee> All { get; }
    IQueryable<Employee> AllIncluding(params Expression<Func<Employee, object>>[] includeProperties);
    Employee Find(int id);
    void InsertOrUpdate(Employee employee);
    void Delete(int id);
    void Save();
}
Then the Repository class called EmployeeRepository  
public class EmployeeRepository : IEmployeeRepository
{
    HRContext context = new HRContext();

    public IQueryable<Employee> All
    {
        get { return context.Employees; }
    }

    public IQueryable<Employee> AllIncluding(params Expression<Func<Employee, object>>[] includeProperties)
    {
        IQueryable<Employee> query = context.Employees;
        foreach (var includeProperty in includeProperties) {
            query = query.Include(includeProperty);
        }
        return query;
    }

    public Employee Find(int id)
    {
        return context.Employees.Find(id);
    }

    public void InsertOrUpdate(Employee employee)
    {
        if (employee.Id == default(int)) {
            // New entity
            context.Employees.Add(employee);
        } else {
            // Existing entity
            context.Entry(employee).State = EntityState.Modified;
        }
    }

    public void Delete(int id)
    {
        var employee = context.Employees.Find(id);
        context.Employees.Remove(employee);
    }

    public void Save()
    {
        context.SaveChanges();
    }

    public void Dispose() 
    {
        context.Dispose();
    }
}

我从以下位置获取soruce代码:http://blogs.msdn.com/b/wriju/archive/2013/08/23/using-repository-pattern-in-entity-framework.aspx

例如,对于通用存储库:

public interface IGenericRepository<T> where T : class {
    IQueryable<T> GetAll();
    IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
    void Add(T entity);
    void Delete(T entity);
    void Edit(T entity);
    void Save();
}

其中T是所有实体的基本实体。以下是完整的通用示例:http://www.tugberkugurlu.com/archive/generic-repository-pattern-entity-framework-asp-net-mvc-and-unit-testing-triangle

我自己找到了!如果有人面临同样的问题,这里有解决方案。我写了这个方法:

public string getKey<T>() where T :new()
   {
       T _obj = new T();           
       return context.CreateEntityKey(_obj.ToString().Split('.')[2], _obj).EntityKeyValues[0].Key;
   }

Wich返回对象的第一个主键(在我的情况下,这就足够了(

并像这样使用:

string sKey = getKey<GruposComerciales>();

现在我可以在我的存储库中编写一个通用的saveorupdate方法了。非常感谢。

您可以通过Metadataworkspace查询主键的所有部分

IDictionary<string, ICollection<EdmMember>> dict = // create instance ...    
MetadataWorkspace.GetItems<EntityContainer>(DataSpace.CSpace)
                             .First()
                             .BaseEntitySets
                             .ToList()
                             .ForEach(s => dict.Add(s.ElementType.Name, s.ElementType.KeyMembers));

有了这个,我将主键的已定义属性放入字典中以备将来使用。