3 回答

TA貢獻1817條經驗 獲得超14個贊
問題是 userDoa 未在您的 DbContext 中注冊實體。
還,
public class UsersDao : GenericDao<UsersDo>, IUsers
{
public UsersDao(DataContext context) : base (context) {}
...
}
我相信不需要。該問題與您的通用存儲庫無關。
public class DataContext : DbContext
{
public virtual DbSet<UserDo> UserDos { get; set; }
}
public class UserDo
{
[Key]
public int UserId {get;set}
public string Username {get;set}
}
然后
var result = new UserContext().Find(x => x.Username == "John");

TA貢獻1842條經驗 獲得超21個贊
你能試試這個
public class UserContext : DbContext
{
public DbSet<UsersDo> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<UsersDo>()
.HasKey(e => e.UsersId);
base.OnModelCreating(modelBuilder);
}
}
public class Repo<T> where T : class
{
private readonly DbSet<T> dbSet;
public Repo(DbContext context)
{
dbSet = context.Set<T>();
}
public T Find(Expression<Func<T, bool>> filter = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderby = null, string includeProperties = "")
{
IQueryable<T> query = dbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (orderby != null)
{
query = orderby(query);
}
// If you use the First() method you will get an exception when the result is empty.
return query?.FirstOrDefault();
}
}
-------- 測試代碼
internal class Program
{
private static void Main(string[] args)
{
var usersDao = new Repo<UsersDo>(new UserContext());
var r = usersDao.Find(x => x.Username == "username");
}
}

TA貢獻1111條經驗 獲得超0個贊
我強烈推薦一種簡化的存儲庫模式,這將有助于模擬您的數據源以進行測試,并提供更大的靈活性。我不建議使用通用存儲庫,而是將存儲庫類似于控制器。(我為一組特定的操作提供數據)這減少了依賴引用的數量,盡管有利于 SRP 而不是 DNRY。
例如:
public class OrderRepository : IOrderRepository
{
private MyDbContext Context
{
return _contextLocator.Get<MyDbContext>() ?? throw new InvalidOperation("The repository must be called from within a context scope.");
}
IQueryable<Order> IOrderRepository.GetOrders()
{
var query = Context.Orders.Where(x => x.IsActive);
return query;
}
IQueryable<Order> IOrderRepository.GetOrderById(int orderId)
{
var query = Context.Orders.Where(x => x.IsActive && x.OrderId == orderId);
return query;
}
Order IOrderRepository.CreateOrder( /* Required references/values */)
{
}
void IOrderRepository.DeleteOrder(Order order)
{
}
}
通過返回 IQueryable,消費代碼可以保持對可選過濾條件、排序、分頁和對數據的操作的控制,而不會觸發不必要的數據讀取。不需要用于過濾、排序的復雜表達式參數或用于管理分頁的額外參數。存儲庫充當 IsActive、授權檢查等所需過濾器的看門人。存儲庫還可以充當實體工廠,確保在創建新實體時提供所有必填字段和引用。我還讓存儲庫管理刪除操作,以確保強制執行所有驗證和完整性,以及審計記錄,并處理軟刪除場景。(活躍)
有些人回避使用 IQueryable,因為它會將 EF 主義“泄漏”到控制器中。然而,它泄露它們只不過是傳遞表達式以試圖抽象出 EF 的復雜方法。每個條件表達式都同樣容易需要符合 EF-isms。(即傳遞引用實體上的私有方法或靜態方法的 order-by 表達式)
像這樣的存儲庫模式(相對于只讓代碼訪問 DbSet)的好處是易于測試。模擬存儲庫只需要返回 aList<T> AsQueryable并且您的控制器等可以單獨測試。它還為所需的過濾器和針對實體的操作提供了很好的集中化。
- 3 回答
- 0 關注
- 102 瀏覽
添加回答
舉報