可能是一个愚蠢回答的问题,但是:有没有办法定义一个IQueryable,然后在不同的上下文中重用它?
Somethink喜欢(Pseudocode):
public IQueryable<myItem> MyQuery()
{
using(MyContext context = new MyContext())
{
return (from myItem in context.MyItems
select ...);
}
}
这将以下面的“某种”方式使用。
public void MyMethod()
{
using(MyContext context = new MyContext())
{
context.ExecuteQueryUnderContext(MyQuery());
}
using(MyContext context2 = new MyContext())
{
context2.ExecuteQueryUnderContext(MyQuery());
}
}
由于
答案 0 :(得分:2)
你可以使用编译的查询;
public static readonly Func<MyContext, IQueryable<MyItem>> dbGetMyItems =
CompiledQuery.Compile<MyContext, IQueryable<MyItem>>
(context) => from myItem in context.MyItems
select ...);
然后称之为;
public void MyMethod()
{
using(MyContext context = new MyContext())
{
var query = dbGetMyItems(context);
}
}
这也为您提供了缓存查询计划的好处,从而提高了性能
答案 1 :(得分:2)
您可以将查询定义为未知现有查询的函数:
// You can add any paramaters you want to this method
// You can also turn this into an extension method
public Func<IQueryable<TItem>, IQueryable<TItem>> MyQuery()
{
return (IQueryable<TItem> items) => (items.Select...);
}
然后像这样使用它:
using (var context = new MyContext())
{
return MyQuery(context.Items).ToList();
}
或者像这样:
using (var context = new MyContext())
{
return MyQuery(context.Items.Where(item.Size > 3)).FirstOrDefault();
}
这样您就可以重复使用甚至链接查询。
或者甚至喜欢这样:
public Item GetItem(Func<IQueryable<TItem>, IQueryable<TItem>> query)
{
using (var context = new MyContext())
{
return query(context.Items).SingleOrDefault();
}
}
答案 2 :(得分:1)
我会将上下文作为Query方法的参数传递
public IQueryable<myItem> MyQuery(MyContext context)
{
return (from myItem in context.MyItems
select ...);
}
public void MyMethod()
{
using(MyContext context = new MyContext())
{
var query = MyQuery(context);
}
}
答案 3 :(得分:1)
public static class Extension
{
public static IQueryable<MyItem> MyQuery(this IQueryable<MyItem> items, int someId)
{
return items.Where(x => x.ID == someId);
}
}
使用它:
using(MyContext context = new MyContext())
{
var item = context.MyItems.MyQuery(5);
}
答案 4 :(得分:0)
您可以使用我的助手:
public static class QueryHelper
{
static object Get_FieldValue(object obj, string name, bool isBase)
{
if (isBase)
{
var _internalContext2 = obj.GetType().BaseType.GetField(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField);
return _internalContext2.GetValue(obj);
}
var _internalContext = obj.GetType().GetField(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField);
return _internalContext.GetValue(obj);
}
static FieldInfo Get_Field(object obj, string name, bool isBase)
{
if (isBase)
{
var _internalContext2 = obj.GetType().BaseType.GetField(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField);
return _internalContext2;
}
var _internalContext = obj.GetType().GetField(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField);
return _internalContext;
}
static object Get_PropertyValue(object obj, string name, bool isBase)
{
if (isBase)
{
var _internalContext2 = obj.GetType().BaseType.GetProperty(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
return _internalContext2.GetValue(obj);
}
var _internalContext = obj.GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
return _internalContext.GetValue(obj);
}
static PropertyInfo Get_Property(object obj, string name, bool isBase)
{
if (isBase)
{
var _internalContext2 = obj.GetType().BaseType.GetProperty(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
return _internalContext2;
}
var _internalContext = obj.GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
return _internalContext;
}
public static void SetInternalContextOfQuery(object old, object newobj)
{
var _internalQuery = Get_Field(old, "_internalQuery", false);
var value = _internalQuery.GetValue(old);
var _internalContext = Get_Field(value, "_internalContext", false);
var _newInternalContext = Get_Property(newobj, "InternalContext", false);
var _internalContextValue = _newInternalContext.GetValue(newobj);
_internalContext.SetValue(value, _internalContextValue);
var _ObjectContext = Get_Property(_internalContextValue, "ObjectContext", false);
var _ObjectContextValue = _ObjectContext.GetValue(_internalContextValue);
var _objectQuery = Get_Field(value, "_objectQuery", false);
var _objectQueryValue = _objectQuery.GetValue(value);
var _providerProperty = Get_Property(_objectQueryValue, "ObjectQueryProvider", false);
var justV = _providerProperty.GetValue(_objectQueryValue);
var _provider = Get_Field(_objectQueryValue, "_provider", true);
var _providerValue = _provider.GetValue(_objectQueryValue);
var _provider_context = Get_Field(_providerValue, "_context", false);
var context = Get_Property(_objectQueryValue, "Context", false);
_provider_context.SetValue(_providerValue, _ObjectContextValue);
var _query = Get_Property(_objectQueryValue, "QueryState", false);
var _queryValue = _query.GetValue(_objectQueryValue);
var _query_context = Get_Field(_queryValue, "_context", true);
//context.SetValue(_objectQueryValue, _ObjectContextValue);
_query_context.SetValue(_queryValue, _ObjectContextValue);
var expersionProperty = Get_Property(value, "Expression", false);
var expersion = (System.Linq.Expressions.MethodCallExpression)Get_PropertyValue(value, "Expression", false);
var result = System.Linq.Expressions.Expression.Lambda(expersion).Compile();
var target = (System.Runtime.CompilerServices.Closure)Get_PropertyValue(result, "Target", false);
var exProvider = Get_FieldValue(target.Constants[0], "_provider", true);
var exProviderField = Get_Field(exProvider, "_context", false);
exProviderField.SetValue(exProvider, _ObjectContextValue);
var ex_queryProvider = Get_PropertyValue(target.Constants[0], "QueryState", true);
var ex_queryProviderField = Get_Field(ex_queryProvider, "_context", true);
//System.Linq.Expressions.Expression.Call()
ex_queryProviderField.SetValue(ex_queryProvider, _ObjectContextValue);
var ObjectQuery = Get_PropertyValue(value, "ObjectQuery", false);
var QueryState = Get_PropertyValue(ObjectQuery, "QueryState", false);
var _expression = Get_Field(QueryState, "_expression", false);
var a = expersion.Arguments.ToArray();
List<System.Linq.Expressions.ConstantExpression> items = new List<System.Linq.Expressions.ConstantExpression>();
foreach (var item in ((System.Runtime.CompilerServices.Closure)result.Target).Constants)
{
items.Add(System.Linq.Expressions.Expression.Constant(item));
}
System.Linq.Expressions.MethodCallExpression methodCall =
System.Linq.Expressions.Expression.Call(expersion.Method, items);
//var exV= System.Linq.Expressions.Expression.Lambda(methodCall);
_expression.SetValue(QueryState, methodCall);
}
}
用法:
IQueryable<DataBase.Models.UserInfo> query = null;
using (var context = new HealthFamilyContext(false))
{
query = from p in context.UserInfoes where p.Id == 1 select p;
}
using (var context = new HealthFamilyContext(false))
{
QueryHelper.SetInternalContextOfQuery(query, context);
var data = query.ToList();
}