mikeobrien.net Curriculum Vitae Blog Labs
Monday, December 28, 2009

Today I had to write some code that had nullable parameters that could filter the results of a Linq query. At first I was doing “if” statements on the nullable parameters to determine if they needed to be applied. This was pretty verbose so I came up with a more succinct approach with conditional Linq extension methods.

First define conditional extension methods on IQueryable<>:

public static class IQueryableExtensions
{
    public static IQueryable<T> Where<T>(this IQueryable<T> query, bool condition, 
        System.Linq.Expressions.Expression<Func<T, bool>> predicate)
    {
        return condition ? query.Where(predicate) : query;
    }

    public static IQueryable<T> Take<T>(this IQueryable<T> query, bool condition, int count)
    {
        return condition ? query.Take(count) : query;
    }

    public static IQueryable<T> Skip<T>(this IQueryable<T> query, bool condition, int count)
    {
        return condition ? query.Skip(count) : query;
    }

    // ...
}

Then you get a nice fluent way to conditionally apply the parameters:

public List<Template> EnumerateTemplates(
    Guid accountId,
    int? startIndex,
    int? maxResults,
    Guid? groupId,
    bool? includeSubGroups,
    DateTime? olderThan,
    DateTime? newerThan)
{
    using (IRepository<Template> templates = Context.Current.Create<IRepository<Template>>())
    {
        var selectedTemplates = templates.
            Where(t => t.Account.Id == accountId).
            Where(groupId.HasValue, t => t.Group.Id == groupId.Value).
            Where(!groupId.HasValue && includeSubGroups.HasValue && 
                  !includeSubGroups.Value, t => t.Group == null).
            Where(olderThan.HasValue, t => t.Created < olderThan.Value).
            Where(newerThan.HasValue, t => t.Created > newerThan.Value).
            Take(maxResults.HasValue, maxResults.Value).
            Skip(startIndex.HasValue, startIndex.Value - 1);

        return selectedTemplates.ToList();
    }
}
C# | Linq | NHibernate
Monday, December 28, 2009 9:34:05 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  |  Trackback
Saturday, December 12, 2009

Here are the slides and code from the lightning talk on Map/Reduce with Linq and F#:

MapReduceLinqFSharpDemo.zip (310.77 KB)
F# | Linq | Presentation
Saturday, December 12, 2009 4:39:27 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  |  Trackback
Tuesday, September 22, 2009

Raja Venkatesh has a nice query visualizer for Linq to Entities. Follow the instructions on the site for the install and fire up VS. Break after a query and select the “RVs’ …” visualizer on the results of the query:

image

And you get this:

image

Thanks Raja!

Tuesday, September 22, 2009 8:29:06 PM (GMT Daylight Time, UTC+01:00)  #   |  Comments [2]  |  Trackback
Tuesday, November 18, 2008

One thing I really love about Linq is how succinctly you can write import and export code. I've had to do this many times before Linq and it always felt kludgy no matter how clean you did it (Especially building xml documents). I think the decision to bake a set based syntax into C# and VB.NET was a great idea. So here is yet another Linq code sample, aren't there already a million of them out there??

Exporting data from a SQL Server table to xml using Linq2Sql and Link2Xml:

TestDataContext dataContext =
    new TestDataContext(@"Data Source=localhost;
        Initial Catalog=Test;Integrated Security=True");

XDocument export = new XDocument(
    new XElement(
        "clients",
            new XComment("This is a comment!"),
            from client in dataContext.Clients
            orderby client.State, client.City 
            select new XElement(
                "client",
                    new XAttribute("id", client.Id.ToString()),
                    new XElement("name", new XText(client.Name)),
                    new XElement("address", new XText(client.Address)),
                    new XElement("address2", new XText(client.Address2)),
                    new XElement("city", new XText(client.City)),
                    new XElement("state", new XText(client.State)),
                    new XElement("zip", new XText(client.Zip)),
                    new XElement("comments", new XCData(
                        string.Format("{0} is based out of {1}.", 
                        client.Name, client.State)))
                )
            )
        );
export.Save(@"D:\Temp\Clients.xml");

Importing data from an xml document to a SQL Server table using Linq2Xml and Linq2Sql (And as Anon pointed out we can do a direct cast since the XAttribute (And XElement) class define explicit conversion operators for primitive types. On that note we also dont need to check if the XElement or XAttribute is null. The Linq2Sql entity defines fields (Or properties) as nullable types and the XElement and XAttribute classes define conversion operators for nullable primitive types. So if an attribute or element does not exist the entity value is simply set to null.):

TestDataContext dataContext =
    new TestDataContext(@"Data Source=localhost;
        Initial Catalog=Test;Integrated Security=True");

XDocument document = XDocument.Load(@"D:\Temp\Clients.xml");

var clients = from client in document.Element("clients").Elements("client")
    select new Client()
    {
        Id = (int)client.Attribute("id"),
        Name = (string)client.Element("name"),
        Address = (string)client.Element("address"),
        Address2 = (string)client.Element("address2"),
        City = (string)client.Element("city"),
        State = (string)client.Element("state"),
        Zip = (string)client.Element("zip")
    };

foreach (var client in clients)
    dataContext.Clients.InsertOnSubmit(client);

dataContext.SubmitChanges();
Tuesday, November 18, 2008 2:10:56 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [2]  |  Trackback
Creative Commons License