使用LINQ to SQL进行动态查询

10
我需要找出是否有可能使用LINQ动态构建查询,动态选择要执行查询的表格。
以下是我将要实现的示例:
//Not working,just for example

public List<dynamic> _getGenericList(String tableName)
    {
        var l = from a in db.//I need to use here tableName
                  select a;

        return l.ToList<dynamic>();
    }

有没有办法使这成为可能?


你可以参考以下文章和答案:http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx http://social.msdn.microsoft.com/Forums/eu/linqprojectgeneral/thread/d9ffe9a1-59c3-4776-900a-4b45e0b4abcf https://dev59.com/rVzUa4cB1Zd3GeqP2FFA http://www.west-wind.com/weblog/posts/2007/Aug/13/LINQ-to-SQL-and-Dynamic-Queries-and-Expressions - Saw
我会尝试在那些链接中搜索。如果我找到有用的东西,我会告诉你。 - benVG
祝你好运,我认为这对你来说会非常容易! - Saw
5个回答

4
如果查询非常简单,您可以动态创建标准的 SQL 语句并执行它,这是最简单的方法,而不需要使用处理器密集的反射和复杂的代码。
var query = "SELECT * FROM " + tableName;
var res = context.ExecuteQuery<dynamic>(query).ToList();

1
这将为您提供一个匿名类型,但不是动态结果! - Saw
1
我不能使用其他方式,在项目中我们只能使用LINQ to SQL,这是客户的要求之一(它是一个现有应用程序的插件)。 - benVG
然而,它是一个有用的替代方案 :) - benVG
@benVG - 然后您需要使用反射从表名获取表的类型并创建此对象的实例,据我所知,您无法在linq中完成此操作。 - CR41G14

1

我找到了一种方法来做这件事,但我不确定是否要使用这段代码。如果您有一个包含两个表的DataContext:

PrimaryTable 
    ID,
    FirstValue,
    SecondValue

SecondaryTable
    ID,
    FirstSecondaryValue

您可以使用以下的DataHelper类:
class DataHelper
{
    public MyDatabaseDataContext db = new MyDatabaseDataContext();

    List<dynamic> GetDynamicList<T>() where T : class
    {
        System.Data.Linq.Table<T> table = db.GetTable<T>();

        var result = from a in table select a;

        return result.ToList<dynamic>();
    }

    public List<dynamic> GetWhatIWant(string tableName)
    {
        Type myClass = Type.GetType("DynamicLinqToSql." + tableName);
        MethodInfo method = typeof(DataHelper).GetMethod("GetDynamicList", BindingFlags.NonPublic | BindingFlags.Instance);
        method = method.MakeGenericMethod(myClass);
        return (List<dynamic>)method.Invoke(this, null);
    }
}

然后,您可以创建一个DataHelper实例并调用GetWhatIWant方法,将表名作为参数传入。
var dataHelper = new DataHelper();

List<dynamic> myFirstList = dataHelper.GetWhatIWant("PrimaryTable");

for (int i = 0; i < 5 && i < myFirstList.Count; i++)
{
    System.Console.WriteLine(String.Format("{0} - {1}", myFirstList[i].FirstValue.ToString(),  myFirstList[i].SecondValue.ToString()));
}

List<dynamic> mySecondList = dataHelper.GetWhatIWant("SecondaryTable");

for (int i = 0; i < 5 && i < mySecondList.Count; i++)
{
    System.Console.WriteLine(mySecondList[i].FirstSecondaryValue.ToString());
}

System.Console.ReadKey();

0

我知道这篇文章有点老了,但如果你像我一样在寻找答案,那么也许这篇文章能帮到你。我直接使用 .NET ObjectContext 而不是 DataContext 数据源。如果你正在使用 DataContext 版本,那么你可以简单地使用 queryResults = myGlobalContext.ExecuteQuery<dbGenericData>(query).ToList();,我相信它会以同样的方式工作。

如果你在命名和设计方面有标准,比如:

  • 表格的 ID 字段始终为 X 类型(INT、GUID 等)
  • ID 字段始终以 tableNameID 命名,即“表格名称”加上 ID 标签。
  • 等等。

这将使你更容易地构建 ID 字段,只需将“ID”字符串附加到表格名称上即可,并且如果需要,还可以使用可靠的 CAST。

说到CAST,你会在查询字符串中注意到它。你需要修改使用CAST的SQL字符串,例如更改字段长度,如我的nvarChar(50)示例等,以克服从数据库获取各种类型数据的问题。

最后注意:在查询字符串中,你会看到我使用“AS”关键字将DB字段转换为新名称。我将“tableIDField”转换为名称“id”,将“requestedField”转换为名称“dbData”。这使系统能够将来自DB的重命名字段与我们倾倒数据的STRUCT对象容器中的字段匹配。这使你能够构建通用容器来保存返回的数据,而不必担心与DB字段名称匹配。

我不是这方面的专家,但我希望这能帮助到某些人。

private void testMethod(string requestedField, string tableName)
{
    var tableIDField = tableName + "ID";

    var query = "select " + tableIDField + " as id, CAST(" + requestedField + "as nvarchar(50)) as dbData from " + tableName;

    List<dbGenericData> queryResults = null;

    try
    {
        queryResults = myGlobalContext.ExecuteStoreQuery<dbGenericData>(query).ToList();
    }
    catch (Exception ex)
    {
        //Simply ignore any exceptions.  
        //These will need examined to determine best solution to unexpected results.
    }
}
private struct dbGenericData
{
    public dbGenericData(int id, string dbData)
    {
        this = new dbGenericData();
        ID = id;
        DBData = dbData;
    }

    public int ID { get; set; }

    public string DBData { get; set; }

}

-1

您可以使用通用方法并使用db.Set<T>,它将返回基于TDbSet


-2
使用Entity SQL来进行LINQ to SQL查询,你可以在这里找到更多关于Entity SQL的信息:http://esql.codeplex.com

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接