簡體   English   中英

實體框架中的LINQ to SQL通用存儲庫等效項

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM