2014-11-20 6 views
2

Часто один хочет, чтобы отобразить полный результат простых объединений таблиц базы данных:Как сгладить кортежи в результате сетки LinqPad?

from x in tablex 
join y in tabley on x.id equals y.id 
select new { x, y } 

В результате этого, однако, является не то, что вы получаете с эквивалентным заявление SQL:

SELECT * FROM tablex x JOIN tabley y ON x.id = y.id 

SQL дает мне одну таблицу результатов со всеми столбцами из обеих таблиц, в то время как LinqPad возвращает таблицу с двумя столбцами, каждый щелчок на каждом из них необходим для расширения соответствующих объектов.

Есть ли простой способ получить тот же результат, который я получаю от аналогичного SQL в LinqPad?

+0

Хороший вопрос. Обычно я делаю это с помощью большого 'Select', который отображает все поля на верхний уровень, но было бы неплохо, если бы действительно был более« автоматический »способ. –

ответ

0

Вы можете получить все объектные поля/свойства с помощью отражения и заполнить их в одну System.Dynamic.ExpandoObject

Вот простой метод расширения делает это: LINQPad script Flatten extension method

или

void Main() 
{ 
    new {x=1, 
     y = new { a = "a", b = "b" }, 
     DateTime.Now 
    } 
    .Dump("Original") 
    .Flatten(1,false) 
    .Dump("Flattened") 
    ; 
} 

public static class Flattener { 
    public static object Flatten(this object o, int level = 1, bool includeParent = false){ 
     if(level == 0) return o; 
     var members = o.GetMemberValues(level, includeParent); 
     var d = new System.Dynamic.ExpandoObject() as IDictionary<string,object>; 
     foreach(var p in members) d.Add(p.Key, p.Value); 
     return d; 
    } 

    private static IEnumerable<KeyValuePair<string,object>> GetMemberValues(this object o, int level = 1, bool includeParent = true, string keyPrefix = null){ 
     if(level < 0) yield break; 

     var properties = 
      from p in o.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance) 
      let get = p.GetGetMethod() 
      where get != null && get.GetParameters().Length == 0 
      select new { p.Name, Value = get.Invoke(o, null) } 
     ; 
     var fields = 
      from p in o.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance) 
      select new { p.Name, Value = p.GetValue(o) } 
     ; 

     foreach(var m in new []{ properties, fields }.SelectMany(x=>x)) { 
      string mkey = keyPrefix == null ? m.Name : keyPrefix + "." + m.Name; 
      bool empty = true; 
      foreach(var m2 in m.Value.GetMemberValues(level-1, includeParent, mkey)){ 
       yield return new KeyValuePair<string,object>(m2.Key, m2.Value); 
       empty = false; 
      } 
      if(includeParent || empty || level == 0) yield return new KeyValuePair<string,object>(mkey, m.Value); 
     }  
    } 
} 
Смежные вопросы