我编写了这个函数,使用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)。 谢谢你!
答案 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));
有了这个,我把主键的已定义属性放入字典中供以后使用。