Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

301
Views
LINQPad: ¿Cómo agrego una propiedad a cada fila que se descarga?

En LINQPad, con frecuencia quiero volcar alguna tabla SQL, pero agrego una propiedad a cada fila. Por lo general, prefiero lo simple:

 Publishers .Select(p => new { p, AppCount = p.Apps.Count() })

Pero, por supuesto, esto da como resultado una salida desordenada, porque cada elemento tiene el formato de una tabla vertical, con una columna adicional que contiene la propiedad agregada. Podría crear un nuevo objeto, pero eso es muy detallado y se pierden los enlaces transversales de la tabla:

 Publishers .Select(p => new { p.PublisherId, p.Name, p.Added, ..., AppCount = p.Apps.Count() })

Lo que me encantaría es algún tipo de sintaxis de combinación, que crea un objeto dinámico para volcar con la propiedad agregada:

 Publishers .Select(p => p.Merge(new { AppCount = p.Apps.Count() })

Probé algunas formas diferentes de lograrlo: usando JsonConvert.SerializeObject (esto se vuelve loco al tratar de serializar todas las referencias de clave externa y repetir bucles, usando ExpandoObject (no pude encontrar una sintaxis limpia y agradable) y bibliotecas como https://github.com/kfinley/TypeMerger , que tampoco he llegado a trabajar.

¿Alguien ha encontrado una forma limpia de hacer esto? ¿LINQPad tiene algún synax incorporado para esto que pueda usar? ¡Gracias!

ACTUALIZACIÓN: Cargué un script de muestra para demostrar el problema y dejar que cualquiera pruebe sus soluciones en: http://share.linqpad.net/kclxpl.linq

Para ejecutarlo, deberá completar la base de datos Nutshell, lo que puede hacer con el ejemplo "Poblar base de datos de demostración" en LINQPad.

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Puede agregar algunos métodos de extensión para que esto funcione. No recomiendo agregarlos a My Extensions porque requieren importar System.Dynamic , que probablemente no desee para la mayoría de las consultas. Póngalos en otra consulta que importe System.Dynamic y #load cuando lo desee.

 public static class ExpandoObjectExt { // convert object to ExpandoObject, add a property and return as dynamic public static dynamic With<T, TAdd>(this T obj, string propName, TAdd val) { var eo = Util.ToExpando(obj); var objDict = (IDictionary<string, object>)eo; objDict[propName] = val; return eo; } // convert IEnumerable<T> to IEnumerable<dynamic>, adding a property to each object public static IEnumerable<dynamic> With<T, TAdd>(this IEnumerable<T> src, string propName, Func<T, TAdd> valFn) => src.Select(s => s.With(propName, valFn(s))); }

Ahora puedes usar esto como:

 Publishers .With("AppCount", p => p.Apps.Count())

Sin embargo, la conversión a ExpandoObject eliminará cualquier hipervínculo para las propiedades de la colección; puede evitar esto especificando solo un nivel de salida con un .Dump(1) explícito. También puede escribir un Util.ToExpando personalizado (el código está aquí ) que usa Util.OnDemand para crear hipervínculos para las propiedades de la colección.

Además, si desea agregar más de una propiedad, puede escribir variaciones de With que toman múltiples pares o una versión que prueba un ExpandoObject (y IEnumerable<ExpandoObject> ) y se puede encadenar con un estilo fluido.

over 4 years ago · Santiago Trujillo Report

0

Tengo una ligera variación en el método de extensión de NetMage. Prueba esto en su lugar:

 public static object Extendo(this object @object, Action<dynamic> inject) { dynamic e = Util.ToExpando(@object); inject(e); return (object)e; }

La Action<dynamic> permite escribir este código:

 var people = new[] { new { name = "Fred", age = 41 }, new { name = "John", age = 67 }, new { name = "Dave", age = 23 }, }; people .Select(p => p.Extendo(d => d.IsOld = p.age >= 55)) .Dump();

primero

Puedo extender esto ligeramente de nuevo con este método:

 public static object Extendo<T>(this IEnumerable<T> source, Action<T, dynamic> inject) => source.Select(x => x.Extendo(d => inject(x, d)));

Ahora puedo escribir esto:

 people.Extendo((p, d) => d.IsOld = p.age >= 55).Dump();

Obtengo el mismo resultado.

Por supuesto, estos métodos efectivamente devuelven object , por lo que no se pueden realizar más cálculos. Así que probablemente valga la pena ir directamente a Dump . Prueba esto:

 public static void Dump<T>(this IEnumerable<T> source, Action<T, dynamic> inject) => source.Select(x => x.Extendo(d => inject(x, d))).Dump();

Ahora solo escribe esto:

 people.Dump((p, d) => d.IsOld = p.age >= 55);
over 4 years ago · Santiago Trujillo Report

0

Este es un problema difícil de resolver. Parte del problema es que los metadatos que permiten que LINQPad identifique las propiedades cargadas de forma diferida se pierden cuando se sacan de su "entidad" de origen y se mueven a un ExpandoObject, lo que provoca un exceso de ida y vuelta.

Para evitar el dolor, agregué un método Util.Merge a LINQPad 7.2.7 . Aquí está su uso más simple:

 var o1 = new { A = 1, B = 2 }; var o2 = new { C = 3, D = 4 }; Util.Merge (o1, o2).Dump();

y para el problema en cuestión:

 Publishers .Select(p => Util.Merge (p, new { AppCount = p.Apps.Count() }))
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!