我是EF的新手,但我已经编程21年了。我喜欢让事情保持DRY和通用,但我刚刚做的事情有些不对劲,但我无法具体指出问题所在。
我看到EF的每个示例都需要开发人员为每个POCO类创建4个单独的CRUD方法。 因此,我就想着不必这样做,以下是我的解决方案:
模型:
public class Model1 : DbContext
{
public Model1()
: base("name=Model1")
{
}
public virtual DbSet<Member> Members { get; set; }
}
所有业务层的基类:
using System.Data.Entity;
using System.Reflection;
namespace biz
{
public abstract class EFObject<T> where T : EFObject<T>
{
public int Id { get; set; }
internal static readonly string DbSetProperyName = typeof(T).Name + "s";
public static EFCollection<T> Collection
{
get
{
using (var db = new Model1())
{
PropertyInfo p = db.GetType().GetProperty(DbSetProperyName);
DbSet<T> collection = (DbSet<T>)p.GetValue(db);
return new EFCollection<T>(collection);
}
}
}
public void Insert()
{
using (var db = new Model1())
{
PropertyInfo p = db.GetType().GetProperty(DbSetProperyName);
DbSet<T> collection = (DbSet<T>)p.GetValue(db);
collection.Add((T)this);
db.SaveChanges();
}
}
public void Save()
{
if (Id == 0)
Insert();
else
Update();
}
public void Update()
{
using (var db = new Model1())
{
PropertyInfo p = db.GetType().GetProperty(DbSetProperyName);
DbSet<T> collection = (DbSet<T>)p.GetValue(db);
T dbItem = collection.Find(Id);
foreach (PropertyInfo pi in typeof(T).GetProperties())
{
pi.SetValue(dbItem, pi.GetValue(this));
}
db.SaveChanges();
}
}
}
}
通用集合类:
using System.Collections.Generic;
namespace biz
{
public class EFCollection<T> : List<T> where T : EFObject<T>
{
public EFCollection()
{
}
public EFCollection(IEnumerable<T> collection)
{
AddRange(collection);
}
public void Save()
{
foreach (T item in this)
item.Save();
}
}
}
中间层类示例:
namespace biz
{
public class Member : EFObject<Member>
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Client[] Clients;
public Good[] Goods;
public decimal Percentage;
}
}
使用方法:
var member = new biz.Member() { FirstName = "Brad", LastName = "Pitt", Percentage = 1 };//
member.Save();
member = biz.Member.Collection.Find(o=>o.Id == member.Id);
member.FirstName = "Cherry";
member.Save();
这个使用代码是有效的,但我想知道这种方法可能会遇到什么问题?
有一件事让我感到不舒服,可能是因为我对EF还不够了解。在我的更新场景中,我 1) 使用一个会话从集合中获取一个对象,2) 断开连接,3) 更新对象的属性,3) 开始一个新会话,4) 通过主键从数据库中找到匹配的对象(它不再是同一个对象!),5) 通过反射更新它,然后 6) 保存更改。因此涉及两个对象而不是一个对象和反射。我认为我必须“放手”保持原始对象,一旦我得到它,但我不知道如何修复这个问题。