我是EF新手,但我已经编程21年了。我喜欢把事情做得干干净净,一般而言,但是我刚刚做的事情似乎有些错误,但我不能把它放在手指上。EF应该封装在基类中吗?
EF上的每个示例我已经看到,开发人员为每个POCO类创建4个单独的CRUD方法。于是我开始没有做到这一点,这就是我想出了:
型号:
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();
}
}
}
}
泛型集合类:
所有业务层public class Model1 : DbContext
{
public Model1()
: base("name=Model1")
{
}
public virtual DbSet<Member> Members { get; set; }
}
基类:
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)开始新的会话,3)通过主键从数据库(它不再是同一个对象!),4)通过反射更新它,然后5)保存更改。所以有两个对象不涉及一个反射。我想我必须“放开”连接,以便在获取它时保留原始对象,但我不知道如何解决此问题。
没有一次性提交一个对象图的,交易中,n + 1次的查询,仅举几例。这种方法与实体持久性无知的常见EF工作流程是垂直的。它让人联想到活跃的记录,这是一个完全不同于数据库+工作单元的数据访问模式。 –
你也通过继承将实体直接绑定到实体框架。 – Amy
@Amy,是的,这是真的。这是一个小项目。或者,我可以用战略/桥梁模式解决这个问题。对CRUD功能的访问仍然是通过基类。你还注意到了什么吗? – toddmo