我是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