Using StructureMap I want to bind IQueryable<T>
to ApplicationDbContext.Set<T>().AsQueryable()
.
So I can inject like this.
public class Foo
{
public Foo(IQueryable<MyEntity> query)
{
}
}
I've gotten this far
config.For(typeof(IQueryable<>))
.Use(x =>
x.GetInstance<ApplicationDbContext>().Set<TNotWorking>().AsQueryable());
But I can't figure out how to get the TNotWorking
working :) I guess reflection isn't an option here, also I would avoid it if possible.
答案 0 :(得分:1)
正如评论中所指出的那样,不可能在项目中反映或实施每个实体作为一种类型。
最后一种方法可能如下所示。当您创建实现IQueryable<T>
的基类时,添加新实体所需的代码很少,并且当有多个DbContext
可用于注入时也可以工作,这几乎总是如此在任何非平凡的演示应用程序中。
public abstract class QueryableEntityBase<TEntity> : IQueryable<TEntity> where TEntity : class
{
protected QueryableEntityBase(DbContext context)
{
Context = context ?? throw new ArgumentNullException(nameof(context));
Queryable = context.Set<TEntity>().AsQueryable();
}
public Type ElementType => Queryable.ElementType;
public Expression Expression => Queryable.Expression;
public IQueryProvider Provider => Queryable.Provider;
protected IQueryable<TEntity> Queryable { get; }
private DbContext Context { get; }
public IEnumerator<TEntity> GetEnumerator() => Queryable.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => Queryable.GetEnumerator();
}
// You need to create this per entity you want to be injectable
public class MyQueryableEntity : QueryableEntityBase<MyEntity>
{
public MyQueryableEntity(ApplicationDbContext context) : base(context) { }
}
这样做的另一个好处是,您可以按实体更改基础查询/持久性提供程序,方法是使用QueryableEntityBase<T>
更改MonogoDbQueryableEntityBase<T>
基础,IMongoClient
使用DbContext
代替config.For(typeof(IQueryable<>)).Use(typeof(QueryableEntityBase<>));
。
注册应该是这样的(不熟悉StructureMap,你需要注册它的所有类型或扫描程序集)。
QueryableEntity<T>
在一个简单的情况下,你只有一个数据库,你也可以使基类非抽象,只需解析public class QueryableEntityBase<TContext, TEntity> : IContextSetQueryable<TDbContext, TEntity>, IQueryable<TEntity> where TEntity : class, TContext : DbContext
{
private TContext Context { get; }
protected QueryableEntityBase(TContext context)
{
Context = context ?? throw new ArgumentNullException(nameof(context));
Queryable = context.Set<TEntity>().AsQueryable();
}
}
,但就像我说你会遇到每个应用程序一个DbContext的限制迟早,所以最好明确地完成。
或者扩展实现,以便您也可以定义上下文
public interface IContextSetQueryable<TContext, TContext> : IQueryable<TEntity> where TContext : DbContext { }
但是你需要一个额外的界面:
IContextSetQueryable<TContext, TContext> entity
然后将DbContext
注入您的服务。
但是你失去了持久性不可知域的能力,因为你需要能够引用public interface ISomethingDatabase
{
IQueryable<User> Users { get; }
IQueryable<Customer> Customers { get; }
...
}
及其子类型,所以它不是很优雅,你也可以使用数据库特定的接口,比如
import tensorflow as tf
def main(_):
saver = tf.train.Saver()
with tf.Session() as sess:
ckpt = tf.train.latest_checkpoint("/data/lstm_models")
saver.restore(sess, ckpt)
if __name__ == "__main__":
tf.app.run()