- consistent model for working with data from various kinds of sources and formats (XML, SQL, ADO.NET, Datasets, .NET collections etc)
- 3 stages of working with LINQ:
- obtain data source
- create the query
- execute the query
- data sources implements
IEnumerable<>
and are calledqueryable types
IQueryable<>
interface inherits fromIEnumerable<>
- generally it is better to use LINQ via
IQueryable<>
which producesdeferred query
instead of producing result immediately - queries can be executed multiple times
- queries can be forced immediate execution via
Count()
,Max()
,ToList()
orToArray()
etc. - LINQ to DB libraries (like EntityFramework) usually are implemented via
Expression Trees
Entity Framework: Change Tracking
- tracked entities are saved during
SaveChanges()
call - entities being tracked when they are:
- returned from DB
- attached to context
- added as subentity
- tracking can be disabled (
AsNoTracking()
i.e.)
Further read:
Entity Framework: eager and lazy loading
- lazy loading:
- delaying load of data until we specifically request for it
- i.e. accessing
customer.Address
loads Address of a customer in the background via separate SQL query
- property needs to be public, virtual
- context.Configuration.ProxyCreationEnabled should be true
- context.Configuration.LazyLoadingEnabled should be true
- to disable lazy loading completely
Context.Configuration.LazyLoadingEnabled = false;
- eager loading
- opposite of lazy loading
- loads related entities as part of the query
- done via
.Include()
query
Further read:
https://www.entityframeworktutorial.net/lazyloading-in-entity-framework.aspx
https://www.entityframeworktutorial.net/eager-loading-in-entity-framework.aspx
Pattern matching
Pattern matching is used for:
- testing expression to check if some value have certain characteristics
- safer compare because ‘==’ and ‘!=’ can be overloaded
Examples:
a is int number
sequence is IList<T> list
switch statement:
command switch { Operation.SystemTest => RunDiagnostics(), Operation.Start => StartSystem(), Operation.Stop => StopSystem(), Operation.Reset => ResetToReady(), _ => throw new ArgumentException("Invalid enum value for command", nameof(command)), };
switch with ranges:
tempInFahrenheit switch { (> 32) and (< 212) => "liquid", < 32 => "solid", > 212 => "gas", 32 => "solid/liquid transition", 212 => "liquid / gas transition", };
collection pattern matching:
array is [1,1,2,3,5,8, ..]
Further read:
https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/functional/pattern-matching
Reflection
- obtain information about types and members at runtime
- create instances, invoke or access them
- dynamic code generation
Further read:
https://learn.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/reflection