最近我在練習設計倉儲模式
我是採用.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才能這樣寫,這部分暫時還不清楚
依照我在文章下方討論中的回覆,沒想到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");
以上為我提供的修改方向。
※程式碼未經測試,使用可能需要調整。
你好,後來我的修該方法跟你們的算比較接近
只是我對Expression這個頗為好奇
為什麼要這樣寫,我以前不常用介面就算有
也還是用一般的LINQ TO SQL來寫,所以這邊我可能有比較多的疑問
你使用的LINQ的x => x.a == b就是一個傳回bool的表達式阿,你也可以詳細參考官方關於個個LINQ語法的介紹,關於SQL的部分有的時候為了提升效能也會建議將表達式往外寫,你也可以找找相關文章。
固定回傳User 用泛型沒意義吧
要想想怎麼修改你的設計
如果真的要那樣寫,就試試:
public TEntity QueryByID(string ID, string PassWord)
{
var query = _context.Users.Where(x => x.Account == ID).FirstOrDefault();
return query as TEntity;
}