iT邦幫忙

0

倉儲模式問題請教

  • 分享至 

  • xImage

最近我在練習設計倉儲模式

我是採用.Net 5

目前有個問題,他會顯示這個錯誤

無法將類型 'Models.Enitites.User' 隱含轉換成 'TEntity'	

我的程式碼大概是這樣

public class BaseRepository<TEntity> : IBaseRepository<TEntity> where TEntity : class, new()
    {
        private Context _context;
        public BaseRepository(Context context)
        {
            this._context = context;
        }
        public TEntity QueryByID(string ID, string PassWord)
        {
            var query = _context.Users.Where(x => x.Account == ID).FirstOrDefault();

            return query;
        }
    }

我傳入的型別是User這個CLASS
我想請問這個該怎麼改

可能還有些細節我沒提到,不知道可不可以到我的GIT幫忙看一下呢?萬分感謝
https://github.com/Jarkwoof/BoardCore

更新:
最後我是這樣改

IBaseRepository

    public interface IBaseRepository<TEntity> where TEntity : class
    {
        TEntity QueryByID(Expression<Func<TEntity, bool>> predicate);
    }

BaseRepository

  public TEntity QueryByID(Expression<Func<TEntity, bool>> predicate)
  {
        return  this._context.Set<TEntity>().FirstOrDefault(predicate);
  }

IUserService

    public interface IUserService
    {
        public User GetById(string UserName ,string Password);
    }

UserService

  public User GetById(string ID, string Password)
        {
            var query = _BaseRepository.QueryByID(x=>x.Account == ID && x.Password == Password);
            return query;
        }

只是我對於IBaseRepositorys那邊比較好奇,為什麼要這樣寫?
這樣寫之後我的UserService才能這樣寫,這部分暫時還不清楚

看更多先前的討論...收起先前的討論...
canrong iT邦新手 2 級 ‧ 2022-04-26 09:50:47 檢舉
沒必要使用泛型,因為固定回傳Users。
canrong iT邦新手 2 級 ‧ 2022-04-26 10:24:52 檢舉
也可以嘗試看看像 public static T QueryByID<T> (this MyDB db , Expression<Func<T, bool>> expression) where T : MyInterface => db.Set<T>().FirstOrDefault(expression); 如果expression需要固定為x => x.Account == ID則需要寫好MyInterface 的部分
tenno081 iT邦研究生 4 級 ‧ 2022-04-26 10:52:20 檢舉
你好,我用泛型是因為還有其他功能會用到此方法
canrong iT邦新手 2 級 ‧ 2022-04-26 11:08:39 檢舉
因為你_context.Users傳回的結果固定為Users,如果你想改寫為共用的方法則可以參考我第二個回覆。
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

0
canrong
iT邦新手 2 級 ‧ 2022-04-26 14:30:49
最佳解答

依照我在文章下方討論中的回覆,沒想到interface會這樣寫,因此決定詳細的解釋一下我的想法。
首先,我希望使用擴展的寫法,撰寫一共用方法,基本寫法如下:
DBExtension.cs

public static T QueryByID<T> (this MyDB db , Expression<Func<T, bool>> expression) => db.Set<T>().FirstOrDefault(expression); 

使用方法將類似於此:

db.QueryByID<User>(x => x.Account == "ID");

而後面所補充的

如果expression需要固定為x => x.Account == ID則需要寫好MyInterface 的部分

需要撰寫一interface將想要使用該方法的model繼承它,如下:
IModels.cs

public interface IModels
{
    string Account { get; set; }
}

User.cs

public class User : IModels
{
    ...
}

而Account是這些model固定的Identity,則可以改寫為

public static T QueryByID<T> (this MyDB db , string id) where T : IModels => db.Set<T>().FirstOrDefault(x => x.Account == id); 

而之後使用方法則改變為

db.QueryByID<User>("ID");

以上為我提供的修改方向。
※程式碼未經測試,使用可能需要調整。

看更多先前的回應...收起先前的回應...
tenno081 iT邦研究生 4 級 ‧ 2022-04-26 15:36:33 檢舉

你好,後來我的修該方法跟你們的算比較接近
只是我對Expression這個頗為好奇
為什麼要這樣寫,我以前不常用介面就算有
也還是用一般的LINQ TO SQL來寫,所以這邊我可能有比較多的疑問

canrong iT邦新手 2 級 ‧ 2022-04-26 15:53:00 檢舉

你使用的LINQ的x => x.a == b就是一個傳回bool的表達式阿,你也可以詳細參考官方關於個個LINQ語法的介紹,關於SQL的部分有的時候為了提升效能也會建議將表達式往外寫,你也可以找找相關文章。

tenno081 iT邦研究生 4 級 ‧ 2022-04-26 15:57:42 檢舉

了解,最後能給我一點關鍵字讓我查查嗎?

canrong iT邦新手 2 級 ‧ 2022-04-26 16:21:05 檢舉

SQL的部分查LINQ效能就有了,其餘的大概就是Expression、Func、Extension,還有就是介面與泛型的概念要再多了解一點。

tenno081 iT邦研究生 4 級 ‧ 2022-04-26 16:31:30 檢舉

謝謝,我第一次遇到這種寫法,我再研究看看

0
科科
iT邦好手 8 級 ‧ 2022-04-26 12:12:41

固定回傳User 用泛型沒意義吧
要想想怎麼修改你的設計

如果真的要那樣寫,就試試:

public TEntity QueryByID(string ID, string PassWord)
{
   var query = _context.Users.Where(x => x.Account == ID).FirstOrDefault();

   return query as TEntity;
}

我要發表回答

立即登入回答