views:

989

answers:

2

I need to update values but I am looping all the tables values to do it:

public static void Update(IEnumerable<Sample> samples
    , DataClassesDataContext db)
{
    foreach (var sample in db.Samples)
    {
        var matches = samples.Where(a => a.Id == sample.Id);
        if(matches.Any())
        {
            var match = matches.First();
            match.SomeColumn = sample.SomeColumn;
        }
    }
    db.SubmitChanges();
}

I am certain the code above isn't the right way to do it, but I couldn't think of any other way yet. Can you show a better way?

+3  A: 

With Linq2Sql (or Linq to Entities), there is no way* to update records on the server without retrieving them in full first, so what you're doing is actually correct.

If you want to avoid this, write a stored procedure that does what you want and add it to your model.

I'm not entirely sure if that was your intended question however :)

*: There are some hacks around that use LINQ to build a SELECT statement and butcher the resulting SELECT statement into an UPDATE somehow, but I wouldn't recommend it.

Thorarin
+4  A: 

Yes, there is a simpler way. Much simpler. If you attach your entities to the context and then Refresh (with KeepCurrentValues selected), Linq to SQL will get those entities from the server, compare them, and mark updated those that are different. Your code would look something like this.

public static void Update(IEnumerable<Sample> samples
    , DataClassesDataContext db)
{
    db.Samples.AttachAll(samples);
    db.Refresh(RefreshMode.KeepCurrentValues, samples)
    db.SubmitChanges();
}

In this case, Linq to SQL is using the keys to match and update records so as long as your keys are in synch, you're fine.

Jacob Proffitt
Small semantic correction, it doesn't "mark them updated". What it does is replace the "original value" of each property with the values read from the database. Since the "current value" of each property is unchanged, SubmitChanges will know to update those records that have an original value (that was read from the server) that differs from the current value (that was passed into the method).
Jacob Proffitt
FYI, this will only work when samples is a subset of what exists in the database. Two assumptions exist. 1. No one will delete any records from this table that exist in your samples enumeration. 2. Consequently, your samples collection can not contain any new entries that you have added.
Marc