views:

60

answers:

3

Hi all,

I have a simple query i.e.

var trips = from t in ctx.Trips select t;

The problem is that I have an extra property on the Trip object that needs to be assigned, preferably without iterating through the returned IQueryable.

Does anyone know how to set the value during the query? (i.e. select t, t.property = "value")

A: 

If you don't want to iterate through the sequence of Trips, you are better of directly updating the database using a stored procedure or parameterized query.

If you're worried that the Trips sequence will contain too many items and be slow to process, you could of course add more filtering in the where clause.

If this isn't possible, it's just another reason to do the processing of very large result sets on the database using a stored proc etc.

Otherwise the usual LINQ to SQL approach is something like:

using (var context = new DefaultDataContext())
{
    var defects = context.Defects.Where(d => d.Status==Status.Open);             

    foreach(Defect d in defects)
    {
        defect.Status = Status.Fixed;                     
        defect.LastModified = DateTime.Now;
    }
    context.SubmitChanges();                 
}
Ash
+1  A: 

This would work:

var trips = from t in ctx.Trips select new Trip 
{
    // db properties
    t.ID,
    t.Name,
    t.Description,

    // non-db properties
    SomeValue = 45,
    SomeOtherValue = GetValueFromSomewhereInCode(t.ID)
}

By projecting your database rows into 'new' Trip objects you can set properties that are not populated by LINQ to SQL, without any additional enumeration required. You can also call custom code in your projection because it executes in code, and not as part of the SQL statement sent to the database.

However, the resulting Trip objects are not enabled for change-tracking so bear that in mind (you can't make changes to properties and have them automatically updated via SubmitChanges(), because the data context doesn't know about your Trip objects).

If you need to track changes as well then you will need to enumerate the tracked Trip objects again after you have retrieved them via LINQ to SQL. This isn't really a problem though as it should be an in-memory iteration.

Sam
This solution would be great except that the table I am querying has something like 50 fields in it - preferably I want to find a way to set values without having to list all of the other fields.
DJCasey
Looks like you'll need to re-iterate over the objects then to set the non-mapped properties - just make sure you call ToList() / AsEnumerable() on the IQueryable before re-iterating.
Sam
+2  A: 

First of all, if you never iterate through the results, your code won't run. LINQ is "lazy", meaning that it only computes the next result when you ask for it.

However, if you do really need to do what you ask, try something like this:

Trip SetProperty(Trip t)
{
    t.property = "value";
    return t;
}
var trips = from t in ctx.Trips select SetProperty(t);
Gabe
Thanks, I think this may be what I need. I'll give it a try tomorrow.
DJCasey