Dynamic query using LINQ to SQL

前端 未结 5 1263
我在风中等你
我在风中等你 2021-01-12 02:21

I need to figure out if it is possible to dynamically build a query with LINQ, dynamically selecting the table in which to perform the query.

This is an example of w

相关标签:
5条回答
  • 2021-01-12 02:46

    I've found a way to do it, but I'm not sure if I'd use this code. If you have a DataContext that contains two tables:

    PrimaryTable 
        ID,
        FirstValue,
        SecondValue
    
    SecondaryTable
        ID,
        FirstSecondaryValue
    

    You could use the following DataHelper class:

    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);
        }
    }
    

    Then you can create an instance of your DataHelper and call the GetWhatIWant method, passing in the table name.

    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 讨论(0)
  • 2021-01-12 02:52

    If the query is this simple you can dynamically create a standard sql statement and execute it, this is the most simplest way without using processor heavy reflection and complex code?

    var query = "SELECT * FROM " + tableName;
    var res = context.ExecuteQuery<dynamic>(query).ToList();
    
    0 讨论(0)
  • 2021-01-12 03:02
    
    var esql = "select t from TypeName as t"
    var q = db.CreateQuery(esql);
    
    

    Use entity sql for linq to sql, http://esql.codeplex.com

    0 讨论(0)
  • 2021-01-12 03:03

    I know this is old, but if you are here looking for answers like I was, then maybe this will help. I'm using a .NET ObjectContext directly instead of a DataContext data source. If you are using the DataContext version then you can simply (I hope) use queryResults = myGlobalContext.ExecuteQuery<dbGenericData>(query).ToList(); instead and I'm pretty sure it will work the same way.

    Your tables will be a lot easier to work with if you have standards in naming and design like

    • the ID field for the table is always X type (INT, GUID, etc)
    • the ID field is always named tableNameID, the 'table name' with ID tagged on.
    • etc,

    This will allow you to easily build the ID field by simply appending the 'ID' string onto the table name and will allow you to use a reliable CAST, if needed.

    Speaking of CAST you will notice one in the query string. You will need to modify the use of the SQL string using CAST, changing field lengths like my nvarChar(50) example, etc, to overcome getting various TYPES of data from your database.

    Final note: In the query string you will see I use the 'AS' key word to cast the DB field to a new name. I cast the 'tableIDField' into the name 'id' and I cast the 'requestedField' into the name 'dbData'. This allows the system to match up the renamed fields from the DB into the STRUCT object container we dump the data into. This allows you to construct generic containers to hold the data returned without having to worry about matching up with the DB field names.

    I'm not a guru at this stuff, but I hope this helps somebody out.

    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; }
    
    }
    
    0 讨论(0)
  • 2021-01-12 03:03

    you can Generic Method and use db.Set<T> that return a DbSet Based on T

    0 讨论(0)
提交回复
热议问题