确定在实体框架上插入或更新

时间:2014-05-01 15:30:16

标签: c# entity-framework

我编写了这个函数,使用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(new)或Attach(exists)。 谢谢你!

3 个答案:

答案 0 :(得分:1)

查看方法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

答案 1 :(得分:0)

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

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

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

并像这样使用它:

string sKey = getKey<GruposComerciales>();

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

答案 2 :(得分:0)

您可以通过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));

有了这个,我把主键的已定义属性放入字典中供以后使用。