find a location for property in a new city
Showing posts with label LINQ. Show all posts
Showing posts with label LINQ. Show all posts

Tuesday, 27 March 2012

Reuse Select function in Linq

You can reuse Linq Select functions by defining a delegate Func field that can be used in multiple Linq queries.

I had a few Linq to Objects queries that were querying the same collection but had different Where clauses that were nested between various if statements. The similarity between all of these statements was the Select function. This was quite long itself and it was annoying seeing such repetition. DRY!

So I tried to create a Func parameter that I could just pass into my Select statement which previously, for example could look like this:

ReturningPerson person;
if (iFeelLikeIt)
{
    person = people.Where(person => person.IsNameFunny)
                .Select(person =>
                    new ReturningPerson
                    {
                        DateOfBirth = input.DateBorn,
                        Name = string.Format("{0} {1}",
                            input.FirstName, input.LastName),
                        AwesomenessLevel = input.KnowsLinq ? "High" : "Must try harder",
                        CanFlyJet = false
                    })
                .FirstOrDefault();
}
else
{
    person = people.Where(person => person.Toes == 10)
                .Select(person =>
                    new ReturningPerson
                    {
                        DateOfBirth = input.DateBorn,
                        Name = string.Format("{0} {1}",
                            input.FirstName, input.LastName),
                        AwesomenessLevel = input.KnowsLinq ? "High" : "Must try harder",
                        CanFlyJet = false
                    })
                .FirstOrDefault();
}

This could be modified to work like this:

Expression<Func<InputPerson, ReturningPerson>> selector = (input) =>
    new ReturningPerson
    {
        DateOfBirth = input.DateBorn,
        Name = string.Format("{0} {1}",
            input.FirstName, input.LastName),
        AwesomenessLevel = input.KnowsLinq ? "High" : "Must try harder",
        CanFlyJet = false
    };
ReturningPerson person;
if (iFeelLikeIt)
{
    person = people.Where(person => person.IsNameFunny)
                .Select(selector)
                .FirstOrDefault();
}
else
{
    person = people.Where(person => person.Toes == 10)
                .Select(selector)
                .FirstOrDefault();
}

Follow britishdev on Twitter

Wednesday, 21 July 2010

Test your LINQ quickly and easily without recompiling

Tired of writing some LINQ then building, then attaching the debugger, then refreshing the page, then waiting for it to compile then see the results, but they're wrong so you detach the debugger then make changes then build then...

Here's a cool little tool that lets you run LINQ queries against you DB or Entity Framework or... well, quite a lot of things actually. The great thing is that you can skip the cycle of editing building etc. It's pretty much direct.

You can even swap between the result set, Lambda expression, SQL and Intermediary language (for some reason):

Download it here: http://www.linqpad.net/

Follow britishdev on Twitter

Wednesday, 21 April 2010

LINQ to SQL - Null value cannot be assigned to a member with type System.Int64 which is a non-nullable value type

I am attempting an InsertOnSubmit and it is failing since "The null value cannot be assigned to a member with type System.Int64 which is a non-nullable value type" This LINQ to SQL is driving me crazy. Please help.

The table in the SQL database has a MessageID column which is a BigInt with primary key (NOT NULL IDENTITY 1 1) no Default.

The field looks like this in the designer file to the dbml:
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_MessageId", AutoSync=AutoSync.OnInsert, DbType="BigInt NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)] 
public long MessageId 
{ 
    get 
    { 
        return this._MessageId; 
    } 
    set 
    { 
        if ((this._MessageId != value)) 
        { 
            this.OnMessageIdChanging(value); 
            this.SendPropertyChanging(); 
            this._MessageId = value; 
            this.SendPropertyChanged("MessageId"); 
            this.OnMessageIdChanged(); 
        } 
    } 
}

So the problem is that null cannot be assigned... right. But I'm not passing null! How can I be? I'm using a long (a value type so can't be null by nature).

One workaround I found was making this field nullable but this feels like a hack since it should never be null. Anyway this just moves the problem to the ID not AutoSyncing OnInsert. (AutoSync=OnInsert is set).

Update and solution

Well it took me a while, I even posted on stackoverflow to no avail but finally worked out the problem and wrote about it in this post about optimistic concurrency exceptions on insert although by this time it has manifested itself in a new way since I'm using Entity Framework.

Follow britishdev on Twitter