我需要弄清楚是否有可能动态地使用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>();
}
有办法使这成为可能吗?
如果查询这么简单,您可以动态创建一个标准sql语句并执行它,这是最简单的方法,而不使用处理器繁重的反射和复杂的代码?
var query = "SELECT * FROM " + tableName;
var res = context.ExecuteQuery<dynamic>(query).ToList();
我已经找到了一种方法,但是我不确定是否要使用这段代码。如果您有一个包含两个表的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();
我知道这是旧的,但如果你在这里寻找像我一样的答案,那么也许这将有所帮助。我直接使用。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',并将' requestdfield '转换为名称'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; }
}
您可以使用泛型方法并使用基于T
返回DbSet
的db.Set<T>
var esql = "select t from TypeName as t"var q = db.CreateQuery(esql);之前