简体   繁体   English

如何为LINQ查询构建动态FROM子句?

[英]How to build a dynamic FROM clause for a LINQ query?

I have a standard LINQ query: 我有一个标准的LINQ查询:

var list = from x in SomeDataContext.ViewName
           where //Rest of where clause
           select x;

I would like to know if it is possible to build a dynamic LINQ query so that i can change the SomeDataContext.ViewName at runtime. 我想知道是否可以构建动态LINQ查询,以便我可以在运行时更改SomeDataContext.ViewName

I have about 5 different views, all with the basic columns needed to perform the where clause, but with some different column names for each of other views. 我有大约5个不同的视图,都具有执行where子句所需的基本列,但每个其他视图都有一些不同的列名。

So is it possible to build up the query so that i can use the different context at runtime, when needed? 那么是否可以构建查询以便在需要时可以在运行时使用不同的上下文?

Example: 例:

public void SomeMethod()
{
    var listA = GetList("DataContext.ViewA");
    var listB = GetList("DataContext.ViewB");
    var listC = GetList("DataContext.ViewC");
}

public List<EntityObject> GetList(string dataContextName)
{
    return (from x in /*HERE I WANT TO USE THE dataContextName*/
           where //Rest of where clause
           select x).ToList();
}

You can use Expression Trees to build dynamic LINQ queries. 您可以使用表达式树来构建动态LINQ查询。 Here is an example: http://msdn.microsoft.com/en-us/library/bb882637.aspx 这是一个例子: http//msdn.microsoft.com/en-us/library/bb882637.aspx

Another approach is to use Dynamic LINQ library: http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx 另一种方法是使用动态LINQ库: http//weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

Both approaches are illustrated here: http://www.codeproject.com/Articles/231706/Dynamic-query-with-Linq 这两种方法都在这里说明: http//www.codeproject.com/Articles/231706/Dynamic-query-with-Linq

Predicate Builder from this example uses Expression Tree approach. 此示例中的Predicate Builder使用表达式树方法。

In general, Dynamic LINQ is easier to implement but Expression Tree is more type-safe. 通常,Dynamic LINQ更容易实现,但Expression Tree更加类型安全。

Just add another layer of indirection: 只需添加另一层间接:

public void SomeMethod()
{
    var listA = GetList("DataContext.ViewA");
    var listB = GetList("DataContext.ViewB");
    var listC = GetList("DataContext.ViewC");
}

public List<EntityObject> GetList(string dataContextName)
{
    return (from x in GetSpecificSource(dataContextName)
           where //Rest of where clause
           select x).ToList();
}

public IEnumerable<MyType> GetSpecificSource(string dataContextName)
// Or: public IQueryable<MyType> GetSpecificSource(string dataContextName)
{
    // ToDo: Return the correct source depending on the name. E.g.:
    switch(dataContextName)
    {
        case "DataContext.ViewA":
            return DataContext.ViewA;
        case "DataContext.ViewB":
            return DataContext.ViewB;
        case "DataContext.ViewC":
            return DataContext.ViewC;
    }
}

Update on how to use reflection 更新如何使用反射

Retrieve a value from a field with a desired name: 从具有所需名称的字段中检索值:

var fieldName = "ViewA";
var fieldFound = type.GetField(fieldName, BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

if(fieldFound != null)
{
    return fieldFound.GetValue(instance);
}

Retrieve a value from a property with a desired name: 从具有所需名称的属性中检索值:

var propertyName = "ViewA";
var propertyFound = type.GetProperty(propertyName, BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

if(propertyFound != null)
{
    return propertyFound.GetValue(instance, null);
}

Retrieve a value from a method with a desired name: 从具有所需名称的方法中检索值:

var methodName = "ViewA";
var methodFound = type.GetMethod(methodName, BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

if(methodFound != null)
   && methodFound.GetParameters().Length == 0)
{
    return methodFound.Invoke(instance, null);
}

So far these are just some simple examples. 到目前为止,这些只是一些简单的例子。 Reflection opens up a complete new bag of issues and questions. 反思开启了一整套问题和问题。 Simply start with the above examples and check if it meets your desires. 只需从上面的例子开始,检查它是否符合您的愿望。 Otherwise simply come back with a new question. 否则只需回来一个新问题。 ;-) ;-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM