C# 使用动态查询从Linq context.ExecuteQuery获取字典对象
我有一个这样的问题C# 使用动态查询从Linq context.ExecuteQuery获取字典对象,c#,linq,dynamic,linq-to-sql,C#,Linq,Dynamic,Linq To Sql,我有一个这样的问题 string sql = " Select Id, CateId From StateCategories "; 我有几个查询选择两到N列,我以前无法确定这一点,因为我的查询是在运行时生成的 我想在不使用任何模型对象的情况下(对于上面的查询)将其结果获取到dictionary对象中。比如(我所尝试的) var-alertCount=context.ExecuteQuery(sql).FirstOrDefault(); 从上面的查询中,我希望Id作为字典的键,CateId
string sql = " Select Id, CateId From StateCategories ";
我有几个查询选择两到N列,我以前无法确定这一点,因为我的查询是在运行时生成的
我想在不使用任何模型对象的情况下(对于上面的查询)将其结果获取到dictionary对象中。比如(我所尝试的)
var-alertCount=context.ExecuteQuery(sql).FirstOrDefault();
从上面的查询中,我希望Id
作为字典的键,CateId
作为字典的值
请注意,在查询中,有两列是整数(至少我保证)。
但它失败了(而且很可能会失败)
无法将值分配给成员“Comparer”。它没有定义setter
有什么更好的方法可以做到这一点呢?在网上进行了一些研究,并从2012年的这篇文章中找到了想法 下面的扩展方法和支持类可用于实现您所追求的目标
public static class DataContextExtensions {
public static IEnumerable<dynamic> ExecuteQuery(this DataContext ctx, string query, DbParameter[] parameters = null) {
using (var cmd = ctx.Connection.CreateCommand()) {
cmd.CommandText = query;
if (parameters != null) cmd.Parameters.AddRange(parameters);
ctx.Connection.Open();
using (var rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection)) {
while (rdr.Read()) {
dynamic row = new DynamicRow();
for (int i = 0; i < rdr.FieldCount; i++) {
row[rdr.GetName(i)] = rdr[i];
}
yield return row;
}
}
}
}
/// <summary>
/// DynamicRow class is similiar to ExpandoObject but with addition of indexer
/// </summary>
public class DynamicRow : DynamicObject {
private readonly Dictionary<string, object> _data = new Dictionary<string, object>();
public object this[string propertyName] {
get {
object result = null;
TryGetMember(propertyName, out result);
return result;
}
set { TrySetMember(propertyName, value); }
}
public override bool TryGetMember(GetMemberBinder binder, out object result) {
return TryGetMember(binder.Name, out result);
}
private bool TryGetMember(string propertyName, out object result) {
return _data.TryGetValue(propertyName.ToLower(), out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value) {
return TrySetMember(binder.Name, value);
}
private bool TrySetMember(string propertyName, object value) {
_data[propertyName.ToLower()] = value;
return true;
}
}
}
这应该让你开始,从那里你应该能够提取你需要的东西。不要说“如果”怎么办?你为什么不自己试一试呢?“如果我用元组而不是字典怎么办”-你试过了吗?我的问题是,如果对于所有的
字典
,元组
,我试过选择多个列。如果您跳过这些what If
我的问题仍然渴望得到答案。:)好吧,你试过一件事,但你想到了其他一些。问之前你试过吗?如果是,发生了什么?你不应该仅仅从你的问题中删除你的想法-你应该尝试它们,并在问题中包含这些信息。不,尝试元组的结果不在上面的问题中。请不要假设投票被否决是因为没有答案——这只是假设这是一个好问题,而依我看不是。
public static class DataContextExtensions {
public static IEnumerable<dynamic> ExecuteQuery(this DataContext ctx, string query, DbParameter[] parameters = null) {
using (var cmd = ctx.Connection.CreateCommand()) {
cmd.CommandText = query;
if (parameters != null) cmd.Parameters.AddRange(parameters);
ctx.Connection.Open();
using (var rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection)) {
while (rdr.Read()) {
dynamic row = new DynamicRow();
for (int i = 0; i < rdr.FieldCount; i++) {
row[rdr.GetName(i)] = rdr[i];
}
yield return row;
}
}
}
}
/// <summary>
/// DynamicRow class is similiar to ExpandoObject but with addition of indexer
/// </summary>
public class DynamicRow : DynamicObject {
private readonly Dictionary<string, object> _data = new Dictionary<string, object>();
public object this[string propertyName] {
get {
object result = null;
TryGetMember(propertyName, out result);
return result;
}
set { TrySetMember(propertyName, value); }
}
public override bool TryGetMember(GetMemberBinder binder, out object result) {
return TryGetMember(binder.Name, out result);
}
private bool TryGetMember(string propertyName, out object result) {
return _data.TryGetValue(propertyName.ToLower(), out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value) {
return TrySetMember(binder.Name, value);
}
private bool TrySetMember(string propertyName, object value) {
_data[propertyName.ToLower()] = value;
return true;
}
}
}
var sql = " Select Id, CateId From StateCategories ";
var dictionary = context.ExecuteQuery(sql).ToDictionary(_ => (int)_.Id, _ => (int)_.CateId);