Posts

Showing posts with the label LINQ

SelectMany - projecting the index of the result

There are 4 overloads of the SelectMany method . Two of them project the index of each source element, for example: string[] sentenceSequences = new string[] {"The quick brown", "fox jumped over","the lazy dog."}; sentenceSequences.SelectMany( // index - the position of the sequence in the sentenceSequences array (sequence, index) => // check if index is on odd position and if so call ToUpper() // ... put the sequence in other array, as the result index % 2 == 0 ? new [] {sequence.ToUpper()} : new [] { sequence } ) .Dump(); But there is no overload for projecting the index of the result also (the index of the element in the result sequence). So here an implementation of it: public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, int, TResult> resul...

TakeFive - what an extension

public static class LinqExtensions { public public static IQueryable<T> TakeFive(this IQueryable<T> query) { return query.Take(5); } }

Generate class from a LINQ projection

Image
using System; using System.Linq; using Microsoft.CSharp; using System.CodeDom; public static class QueryExtensions { public static string GetClassDefinition<T>(this IQueryable<T> query, string className) { var type = typeof(T); var sb = new StringBuilder(); sb.AppendLine(string.Format("public class {0}", className)); sb.AppendLine("{"); using (var provider = new CSharpCodeProvider()) { foreach ( var prop in type.GetProperties()) { var typeRef = new CodeTypeReference(prop.PropertyType); var propertyTypeName = provider.GetTypeOutput(typeRef); if ( !propertyTypeName.StartsWith("<>")) { propertyTypeName = propertyTypeName.Replace("System.Nullable<", String.Empty) .Replace(">","?") .Replace("System.", String.Empty); sb.AppendLine(string.Format("\tpublic {0} {1} {{get; set;}}", propertyTypeName, prop.Name)); } } ...

My Birthday

Image
Today is my birthday and because today my thoughts are only about myself, I had a curiosity about in which years I did celebrate my birthday on Wednesdays ( I like this day of week). With the following LINQ query I found the answer from i in Enumerable.Range(0,29) where (new DateTime(i + 1983,4,6).DayOfWeek) == DayOfWeek.Wednesday select new { year = i + 1983, age = i } which is.. Year Age 1983 0 1988 5 1994 11 2005 22 2011 28 And because my curiosity about me and only me goes mad, I wanted to find out more about each day of week and my birthdays. Enumerable.Range(0,29).ToLookup(i =>new DateTime(i + 1983,4,6).DayOfWeek, i=>new {year = i + 1983,age = i}).OrderBy(d=>(int)d.Key) click on the image to see it in full size Thanks to LINQ Pad.

Totals on Reports using LinqDataSource

Image
One common request for reporting is to show aggregations as well, like sums, averages, counts, etc among with the report itself. So for example if an expenses/charges/profits report shows the list of all products sold in some date/time range, then the person who analyzes the report would like to see and some totals (sum of the costs, sum of the charges, sum of profits and the total number of products), somewhere in the report's bottom. If the number of reports is slightly lower and the features are limited, like the reports need to support only the HTML version, LINQ with LinqDataSource can be the right thing to use, for RAD reports. The control is built so the developers can write less and do more, so basically they set the ContextTypeName, TableName, Select statement if any, WhereParameters, OrderParameters, etc, but this control it doesn't yield the aggregates. I extended the LinqDataSource in the spirit of "write less do more" principle and I changed its default b...

Think LINQ deffered execution like an non-clustered SQL View

LINQ deferred execution is when you create the query, but this is not executed until you need it. So first you tell what you need and you'll get it when is needed by calling methods like ToList, First, Single, etc. var ctx = ... var query = from p in ctx.products where p.enabled == true && c.deleted == false select p; After calling query.ToList(), the LINQ creates the SQL, sends it to server, get the results and then creates the products list. query is an IQueryable<T> object and ToList creates an IList<T> object. An non-clustered SQL View acts pretty same like the LINQ non deferred execution. First you define the query, then you call it or use it in any other queries. CREATE VIEW vwProducts AS SELECT p.* FROM dbo.products p WHERE p.enabled = 1 AND p.deleted = 0 SELECT * FROM vwProducts p WHERE p.description like '%potatoes%' SQL Server will expand the View vwProducts when the last query is executed. So, how to see the first LINQ...

Un bug in LINQ

Image
Am dat de un mic bug in LINQ to SQL, ce m-a facut sa-mi regandesc o abordare dintr-un anumit proiect. Eroarea apare in interiorul DataContext si anume la nivelul asocierii dintre clasele mapate pe tabele in scopul de a evidentia relatia 1:n. Sa explic insa cu un exemplu. Se da o baza de date cu trei tabele, o tabela cu categorii, o tabela cu produse si o tabela History, care contine istoria operatiilor pe celelalte doua. Pentru o anumita inregistrare din Products sau Categories vor exista una sau mai multe intrari(sau niciuna) in tabela History. Stiind un anumit HistoryGUID din Products sau Categories se pot afla inregistrarile din History, adica istoria operatiilor facute pentru o anumita inregistrare din oricare tabele. Cum HistoryGUID este generat automat de SQL Server cu newid(), la inserarea unei noi inregistrari intr-o tabela din cele doua, atunci e asigurata unicitatea lui la nivel de baza de date, conditie necesara pentru a identifica corect cumulul de inregistrari in History a...