15.02.2015 Views

C# 4 and .NET 4

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

linQ to entities ❘ 883<br />

event of the ObjectContext class. This event is fired before the data is written to the store, so you can add<br />

some verification logic to see if the changes should be really done. SaveChanges() returns the number of<br />

entity objects that have been written.<br />

What happens if the records in the database that are represented by the entity classes have been changed<br />

after reading the record The answer depends on the ConcurrencyMode property that is set with the<br />

model. With every property of an entity object, you can configure the ConcurrencyMode to Fixed or<br />

None. The value Fixed means that the property is validated at write time to determine if the value was<br />

not changed in the meantime. None — which is the default — ignores any change. If some properties<br />

are configured to the Fixed mode, <strong>and</strong> data changed between reading <strong>and</strong> writing the entity objects, an<br />

OptimisticConcurrencyException occurs.<br />

You can deal with this exception by invoking the Refresh() method to read the actual information<br />

from the database into the object context. This method accepts two refresh modes configured by a<br />

RefreshMode enumeration value: ClientWins or StoreWins. StoreWins means that the actual information<br />

is taken from the database <strong>and</strong> set to the current values of the entity objects. ClientWins means that the<br />

database information is set to the original values of the entity objects, <strong>and</strong> thus the database values will<br />

be overwritten with the next SaveChanges. The second parameter of the Refresh() method is either a<br />

collection of entity objects or a single entity object. You can decide the refresh behavior entity by entity:<br />

private static void ChangeInformation()<br />

{<br />

//...<br />

int changes = 0;<br />

try<br />

{<br />

changes += data.SaveChanges();<br />

}<br />

catch (OptimisticConcurrencyException ex)<br />

{<br />

data.Refresh(RefreshMode.ClientWins, ex.StateEntries);<br />

changes += data.SaveChanges();<br />

}<br />

Console.WriteLine("{0} entities changed", changes);<br />

//...<br />

code snippet Formula1Demo/Program.cs<br />

linq To enTiTies<br />

In several chapters of this book, you’ve seen LINQ to Query objects, databases, <strong>and</strong> XML. Of course,<br />

LINQ is also available to query entities.<br />

With LINQ to Entities, the source for the LINQ query is ObjectQuery. Because ObjectQuery<br />

implements the interface IQueryable, the extension methods selected for the query are defined with the<br />

class Queryable from the namespace System.Linq. The extension methods defined with this class have a<br />

parameter Expression; that’s why the compiler writes an expression tree to the assembly. You can read<br />

more about expression trees in Chapter 11. The expression tree is then resolved from the ObjectQuery<br />

class to the SQL query.<br />

You can use a simple LINQ query as shown here to return the racers that won more than 40 races:<br />

using (var data = new Formula1Entities())<br />

{<br />

var racers = from r in data.Racers<br />

where r.Wins > 40<br />

orderby r.Wins descending<br />

select r;<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!