![](/img/trans.png)
[英]LINQ to SQL: Check for existence of a generic entity in a generic Repository
[英]LINQ to SQL Generic Repository equivalent in Entity Framework
我正在為我的ORM從LINQ轉換為SQL,再轉換為Entity Framework,並且正在更新存儲庫。 除了通用的以外,所有這些都已完成。 我似乎無法弄清楚如何將Select
方法從現在的方法轉換為可以與EF一起使用的方法。 這是當前代碼:
public T Select(int Id)
{
MetaDataMember PrimaryKey = this.DataContext.Mapping.GetTable(typeof(T)).RowType.DataMembers.SingleOrDefault(
d =>
(d.IsPrimaryKey));
ParameterExpression Param = Expression.Parameter(typeof(T), "e");
var Query = Expression.Lambda<Func<T, bool>>(Expression.Equal(Expression.Property(Param, PrimaryKey.Name), Expression.Constant(Id)), new ParameterExpression[] { Param });
return this.DataContext.GetTable<T>().Single(Query);
}
我沒有寫這篇文章,而是從某人的博客復制過來的,到目前為止,它對我來說是有用的。 我真的不知道它的作用,模棱兩可的想法,但是我無法將其轉換為EF。
所以,我來這里是為了尋求各位女士或先生們的幫助。 如果可能的話,如果知道EF的人可以轉換該語句,我會喜歡的。 如果有其他代碼可以完成同一件事,那么我很樂意。
如果我正確理解該方法,它將基於主鍵返回任何T類型的單個記錄。
我們也有一個通用的存儲庫,但是界面如下所示:
public interface IRepository<T> where T : class
{
void Add(T entity);
void Remove(T entity);
void Attach(T entity);
IQueryable<T> Find();
}
以及我們的通用存儲庫實現:
public class GenericRepository<T> : IRepository<T> where T : class
{
public IQueryable<T> Find()
{
return _ctx.GetEntitySet<T>(); // EF plularization/reflection smarts
}
}
因此,要獲得“發布”的同等記錄:
var postId = 1;
IRepository<Post> repository = new GenericRepository<Post>(); // done by DI in reality
repository
.Find()
.SingleOrDefault(x => x.PostId == postId); // explicit predicate to grab record
這與原始代碼有很大不同-調用代碼指定了主鍵是什么(或標識唯一記錄的方式)。
老實說,嘗試根據恆定的主鍵值動態獲取唯一記錄是非常瘋狂的- 如果它是復合鍵,該怎么辦? 我看不到該代碼將如何工作。
很高興看到其他答案,但我會保持簡單。
如果您想讓代碼獲取基於T的實體集,我可以分享-但是非常簡單。
如果您想要一個方法來獲取一條記錄,請讓調用代碼提供謂詞/鍵:
public T FindSingle(Expression<Func<T,bool>> predicate)
{
return _ctx.GetEntitySet<T>.SingleOrDefault(predicate);
}
然后,例如,如果“ Post”具有“ PostName”和“ PostType”的復合鍵:
var singlePost = repository.FindSingle(post => post.PostName == "Foo" && post.PostType == "Question");
在您的示例中,您的存儲庫決定了您的模型,使每個實體具有單個列的主鍵。
您的存儲庫應該幫助您的模型,而不是對其進行定義。
編輯GetEntitySet<T>
代碼,按要求
public IObjectSet<T> GetEntitySet<T>() where T : class
{
var entityName = _plularizer.Pluralize(typeof(T).Name);
string entitySetName = string.Format("{0}.{1}", EntityContainerName, entityName);
return CreateObjectSet<T>(entitySetName );
}
非常簡單,也很安全,因為_plularizer
的類型為System.Data.Entity.Design.PluralizationService
,它與EF用於創建默認實體集名稱的模塊相同。
EntityContainerName
是您的實體的容器名稱。
_plularizer
實例應為static ,並通過完全鎖定的單例保持線程安全。
HTH。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.