Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

303
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda