私はEFの新人ですが、私は21年間プログラミングしてきました。私は物事をドライとジェネリックにするのが好きですが、私がやったことについて何かが間違っているように見えますが、私はそれに指をかけられません。EFを基本クラスにカプセル化する必要がありますか?
私が見た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)1つのセッションを使用してコレクションからオブジェクトを取得する、2)切断する、3)オブジェクトのプロパティを更新する、3)新しいセッションを開始する、3)一致するオブジェクトをdb(それはもはや同じオブジェクトではありません!)、4)リフレクションによって更新し、次に5)変更を保存します。したがって、1つではなく、2つのオブジェクトが関わっています。私は一度それを取得した元のオブジェクトを維持するために接続の "手放す"と私はこれを修正する方法がわからないと思う。
なしワンショットは、オブジェクトグラフのコミット、トランザクション、N + 1つのクエリ、いくつか例を挙げると。このアプローチは、エンティティが永続性を知らない共通のEFワークフローに垂直です。これはアクティブなレコードを思い起こさせるもので、リポジトリ+作業単位とはまったく異なるデータアクセスパターンです。 –
また、継承を使用してエンティティを直接Entity Frameworkに結び付けています。 – Amy
@Amy、はい、それは本当です。それは小さなプロジェクトです。あるいは、私は戦略/橋のパターンでその問題を解決することができます。 CRUD関数へのアクセスは引き続き基本クラス経由で行われます。あなたが気づいたことが他にありましたか? – toddmo