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 关注
- 85 浏览
添加回答
举报