J'essaie de réécrire un vieil SQL dans Linq à SQL. J'ai une SPUCT avec un groupe avec le rouleau, mais je ne suis pas sûr de ce que l'équivalent Linq serait. Linq a une groupeby mais il ne semble pas que cela prend en charge le rouleau.
Un exemple simplifié des résultats que j'essaie de devenir quelque chose comme ceci: p> Toutes idées sur la manière dont je pourrais obtenir ces résultats à l'aide de Linq à SQL? p> p>
4 Réponses :
Je l'ai eu! Une groupe génériquebywithbriollup. Il ne s'agit que de deux colonnes, mais pourrait facilement être étendu pour soutenir davantage. J'aurai probablement une autre version qui accepte trois colonnes. Les classes de clés / méthodes sont regroupant , groupebymany () et groupebywithrollup (). Les méthodes sous-totales () et grand-tobintes () sont des assistants lorsque vous utilisez réellement le groupeBywithRollup (). Vous trouverez ci-dessous le code, suivi d'un exemple de comment l'utiliser.
class Program
{
static void Main(string[] args)
{
IQueryable<CustomObject> dataItems = (new[]
{
new CustomObject { City = "Seattle", Plan = "Plan B", Charges = 20 },
new CustomObject { City = "Seattle", Plan = "Plan A", Charges = 10 },
new CustomObject { City = "Seattle", Plan = "Plan B", Charges = 20 },
new CustomObject { City = "Seattle", Plan = "Plan A", Charges = 10 },
new CustomObject { City = "Seattle", Plan = "Plan A", Charges = 10 },
new CustomObject { City = "Seattle", Plan = "Plan A", Charges = 10 },
new CustomObject { City = "Portland", Plan = "Plan A", Charges = 10 },
new CustomObject { City = "Portland", Plan = "Plan A", Charges = 10 },
new CustomObject { City = "Portland", Plan = "Plan C", Charges = 30 },
new CustomObject { City = "Portland", Plan = "Plan C", Charges = 30 },
new CustomObject { City = "Portland", Plan = "Plan C", Charges = 30 }
}).AsQueryable();
List<CustomObject> results = dataItems.OrderBy(item => item.City).ThenBy(item => item.Plan).GroupByWithRollup(
item => item.City,
item => item.Plan,
(primaryGrouping, secondaryGrouping) => new CustomObject
{
City = primaryGrouping.Key,
Plan = secondaryGrouping.Key,
Count = secondaryGrouping.Count(),
Charges = secondaryGrouping.Sum(item => item.Charges)
},
item => new CustomObject
{
City = item.Key,
Plan = "All",
Count = item.SubTotal(subItem => subItem.Count),
Charges = item.SubTotal(subItem => subItem.Charges)
},
items => new CustomObject
{
City = "All",
Plan = "All",
Count = items.GrandTotal(subItem => subItem.Count),
Charges = items.GrandTotal(subItem => subItem.Charges)
}
);
foreach (var result in results)
Console.WriteLine(result);
Console.Read();
}
}
class CustomObject
{
public string City { get; set; }
public string Plan { get; set; }
public int Count { get; set; }
public decimal Charges { get; set; }
public override string ToString()
{
return String.Format("{0} - {1} ({2} - {3})", City, Plan, Count, Charges);
}
}
Bah, il y a toujours des bugs là-bas. Lorsque je l'exécute contre les données SQL réelles, il jette des exceptions parce que je dois utiliser l'expression
Cette approche s'est avérée beaucoup plus complexe que nécessaire. Je n'ai pas pu obtenir le regroupement entièrement du côté SQL. En fin de compte, j'ai abandonné cette approche et avons eu la solution acceptée beaucoup plus simple.
J'ai compris une solution beaucoup plus simple. J'essayais de rendre cela plus compliqué que nécessaire. Plutôt que d'avoir besoin de 3-5 classes / méthodes, je n'ai besoin que d'une méthode.
Fondamentalement, vous faites votre tri et regroupez-vous, puis appelle et un exemple de comment l'utiliser: p> sans fil () code> pour obtenir une liste <> code> des éléments avec des sous-totaux et un total total. Je ne pouvais pas comprendre comment générer les sous-totaux et le total du total du côté SQL afin d'être effectué avec Linq aux objets. Voici le code: p>
@ecyrb, bonjour à partir de cinq ans plus tard!
Je ne suis que peu familier avec Linq à SQL ci-dessus et au-delà de la linq standard (aux objets). Cependant, étant donné que vous avez une balise "LINQ" séparée de votre étiquette "LINQ-2-SQL", car vous semblez être principalement intéressé par les résultats (par opposition à l'enregistrement des modifications avec la base de données), et parce que c'est le seul Fonction de regroupement de SQL Server de SQL Server, je vais offrir ma propre solution alternative à personne aujourd'hui avec un besoin similaire. P>
essentiellement, mon L'approche consiste à créer un ".groupby (). Syntaxe de charabia () similaire à la" Ordinateur .Orderby (). Syntaxe () ". Mon extension s'attend à une collection d'objets Igrouping - le résultat que vous obtenez de l'exécution de "GROUPBY ()" - comme source. Il prend ensuite la collection et les déclineille pour revenir à l'objet d'origine avant de grouper. Enfin, il regroupe les données conformément à la nouvelle fonction de regroupement, produisant un autre ensemble d'objets Igrouping et ajoute les objets nouvellement groupés dans l'ensemble des objets source. P>
var rollItUp = dataItems
.GroupBy(g=> new {g.City, g.Plan})
.ThenBy(g=> new {g.City, Plan = (string) null})
.ThenBy(g=> new {City = (string) null, Plan = (string) null})
.Select(s=> new CustomObject {
City = s.Key.City,
Plan = s.Key.Plan,
Count = s.Count(),
Charges = s.Sum(a=> a.Charges)})
.OrderBy(o=> o.City) // This line optional
.ThenBy(o=> o.Plan); // This line optional
Une solution assez intéressante est fournie ici
https://blogs.msdn.microsoft.com/mitsu/2007/12/21/playing-with-linq-grouping-groupbymany/ p>
Il décrit comment Effectuez Groupeby par plusieurs propriétés. I.E: P>
var result = customers.GroupByMany(c => c.Country, c => c.City);