SlideShare ist ein Scribd-Unternehmen logo
1 von 39
Performance trotz Entity
Framework
Dipl. Inform. (FH) André Krämer, M. Sc.
Softwareentwickler, Trainer & Berater
Was machen wir eigentlich
den ganzen Tag?
?
Datenzugriffsalternativen
DataReader (.NET 1.0 Style)
using (connection)
{
SqlCommand command =
new SqlCommand( "SELECT CategoryID, CategoryName FROM Categories;",
connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
Console.WriteLine("{0}t{1}", reader.GetInt32(0), reader.GetString(1));
}
}
else
{
Console.WriteLine("No rows found.");
}
reader.Close();
}
DataReader
• Sehr performant
• Sehr aufwändig
30 % der Arbeitszeit sind
verloren
„if you’re writing ADO.Net code by hand, you’re
stealing from your employer or client.”
Jeremy D. Miller, 7. November 2008,
http://codebetter.com/jeremymiller/2008/11/07/how-to-design-your-data-connectivity-strategy/
(Typed) Datasets
Bewertung Typed Datasets
• Schlechte Performance
• Hoher Speicherverbrauch
• Geringer Entwicklersupport
• Nur bedingt Interoperabel
• …
ORMs (Entity Framework)
NHibernate
OR-Mapper
• Abstrahieren die Datenbank für uns
• Erlauben einen objektorientierten Zugriff auf die Datenbank
• Lassen uns unsere gewohnte Programmiersprache nutzen
• „Schützen(?)“ uns davor SQL schreiben zu müssen
• Sparen Entwicklungszeit
Das Entity Framework macht glücklich!
Foto: © Rostislav Sedlacek | Fotolia.com
Aber leider nicht Jeden
Foto: © Romolo Tavani | Fotolia.com
Typische
Reaktion des
DBA, wenn er
sieht, dass Sie
das Entity
Framework
nutzen
Foto: © Shakzu | Fotolia.com
Ist das Entity Framework wirklich langsam?
Foto: © pkruger | istockphoto.com
Demo
Typische Performancefallen und Lösungen
Source Code unter: https://github.com/AndreKraemer/EFPerformanceDemo
Allerdings ohne zu raten
Foto: © clocki | istockphoto.com
Wir messen!
Foto: © matt_benoit | istockphoto.com
Zusammenfassung
24
Messen Sie statt zu raten!
http://hibernatingrhinos.com/products/EFProf
Legen Sie eine ausreichende Menge an
realistischen Testdaten an
26http://www.red-gate.com/products/sql-development/sql-data-generator/
Laden Sie nicht mehr Daten als benötigt
using (var db = new NorthwindDb())
{
var products = db.Products;
foreach (var product in products)
{
Console.WriteLine("{0}",
product.ProductName);
}
}
SELECT [Extent1].[ProductID] AS [ProductID],
[Extent1].[ProductName] AS [ProductName],
[Extent1].[SupplierID] AS [SupplierID],
[Extent1].[CategoryID] AS [CategoryID],
[Extent1].[QuantityPerUnit] AS
[QuantityPerUnit],
[Extent1].[UnitPrice] AS [UnitPrice],
[Extent1].[UnitsInStock] AS [UnitsInStock],
[Extent1].[UnitsOnOrder] AS [UnitsOnOrder],
[Extent1].[ReorderLevel] AS [ReorderLevel],
[Extent1].[Discontinued] AS [Discontinued]
FROM [dbo].[Products] AS [Extent1]
Laden Sie nicht mehr Daten als benötigt
(Lösung)
var products = db.Products.Select(p
=> new {p.ProductName});
foreach (var product in products)
{
Console.WriteLine("{0}",
product.ProductName);
}
SELECT 1 AS [C1],
[Extent1].[ProductName] AS [ProductName]
FROM [dbo].[Products] AS [Extent1]
28
Laden Sie „Readonly Daten“ nicht in den
Change Tracker
var shippers = db.Shippers.ToList();
for (int i = 0; i < 200 && i <
shippers.Count; i++)
{
var shipper = shippers[i];
Console.WriteLine("{0} - {1}",
shipper.ShipperID,
shipper.CompanyName);
}
var shippers =
db.Shippers.AsNoTracking().ToList();
for (int i = 0; i < 200 && i <
shippers.Count; i++)
{
var shipper = shippers[i];
Console.WriteLine("{0} - {1}",
shipper.ShipperID,
shipper.CompanyName);
}
29
Laden Sie nur die Zeilen, die Sie wirklich
benötigen
var shippers = db.Shippers.ToList();
for (int i = 0; i < 10; i++)
{
Console.WriteLine("{0} - {1}",
shippers[i].ShipperID,
shippers[i].CompanyName);
}
var shippers =
db.Shippers.Take(10).ToList();
foreach (var shipper in shippers)
{
Console.WriteLine("{0} - {1}",
shipper.ShipperID,
shipper.CompanyName);
}
30
Filtern Sie auf dem Server, nicht auf dem
Client
var customers = GetCustomers(db).Where(c =>
c.Country == "Germany");
foreach (var customer in customers)
{
Console.WriteLine("{0} - {1}",
customer.CustomerID, customer.CompanyName);
}
private IEnumerable<Customers>
GetCustomers(NorthwindDb db)
{
return db.Customers;
}
var customers = GetCustomersQry(db).Where(c
=> c.Country == "Germany");
foreach (var customer in customers)
{
Console.WriteLine("{0} - {1}",
customer.CustomerID, customer.CompanyName);
}
private IQueryable<Customers>
GetCustomersQry(NorthwindDb db)
{
return db.Customers;
}
31
Lassen Sie sich nicht durch die Intellisense in
falsche Richtungen leiten
var shippers =
db.Shippers.ToList().Take(10);
foreach (var shipper in shippers)
{
Console.WriteLine("{0} - {1}",
shipper.ShipperID,
shipper.CompanyName);
}
var shippers =
db.Shippers.Take(10).ToList();
foreach (var shipper in shippers)
{
Console.WriteLine("{0} - {1}",
shipper.ShipperID,
shipper.CompanyName);
}
32
Nutzen Sie Find Statt SingleOrDeafault um
Entitäten aus dem Cache zu laden
var s1 =
db.Shippers.SingleOrDefault(c =>
c.ShipperID == 1);
Console.WriteLine("S1: {0} - {1}",
s1.ShipperID, s1.CompanyName);
var s2 =
db.Shippers.SingleOrDefault(c =>
c.ShipperID == 1);
Console.WriteLine("S2: {0} - {1}",
s2.ShipperID, s2.CompanyName);
var shippers =
db.Shippers.Take(10).ToList();
foreach (var shipper in shippers)
{
Console.WriteLine("{0} - {1}",
shipper.ShipperID,
shipper.CompanyName);
}
33
Laden Sie nicht zum Löschen
var maxShipperId = db.Shippers.Max(s
=> s.ShipperID);
var shipper =
db.Shippers.Find(maxShipperId);
db.Shippers.Remove(shipper);
db.SaveChanges();
var maxShipperId = db.Shippers.Max(s
=> s.ShipperID);
// db.Shippers.Find(maxShipperId);
var shipper = new Shippers {ShipperID
= maxShipperId};
db.Shippers.Attach(shipper);
db.Shippers.Remove(shipper);
db.SaveChanges();
34
Behalten Sie Lazy Loading im Auge
var orders = db.Orders.ToList();
foreach (var order in orders)
{
Console.WriteLine("{0} {1}",
order.OrderID,
order.Customers.CompanyName);
}
var orders = db.Orders.Include(o=>
o.Customers).ToList();
foreach (var order in orders)
{
Console.WriteLine("{0} {1}",
order.OrderID,
order.Customers.CompanyName);
}
35
Annotieren Sie Ihr Model korrekt (Im Fall
von Code First)
• public string PreferedCommunication { get; set; }
wird zu nvarchar(max) in der Datenbank!
• [StringLength(50)]
public string PreferedCommunication { get; set; }
wird zu nvarchar(50) in der Datenbank
modelBuilder.Entity<Customers>()
.Property(e=> e.PreferedCommunication)
.IsUnicode(false);
 varchar statt nvarchar
36
Homepage
andre@andrekraemer.de | http://andrekraemer.de | http://andrekraemer.de/blog
Vielen Dank!
Blog
Xing
Facebook
Twitter
Google+
37
Sie haben ein Performance oder
Speicherproblem in Ihrer Anwendung?
Im Rahmen meiner Beratertätigkeit betreue ich seit vielen Jahren Kunden rum um die
Themen Datenzugriffsperformance, Anwendungsperformance und Memory Leak
Analysen.
Kommen Sie bei Bedarf gerne auf mich zu:
andre@andrekraemer.de | http://andrekraemer.de
38
Meine Dienstleistungen
• Schulungen
• ASP.NET / JavaScript / AngularJS
• Xamarin
• Cordova
• TX Text Control
• Infragistics NetAdvantage
• Team Foundation Server
• .NET Datenzugriff (Entity Framework, NHibernate, Micro O/R Mapper)
• Consulting
• Durchführung von Technologieworkshops
• Code- / Architekturreviews
• Analyse von managed Memory Leaks
• Prototypenentwicklung
• Remote Entwickler-Support
• Projektbegleitendes Coaching
• Softwareentwicklung
• Mobile Apps (Android, iOS, Windows 10, Windows 8, Windows Phone)
• Entwicklung von Web-Anwendungen mit ASP.NET und AngularJS
• Entwicklung von Desktop Anwendungen
39andre@andrekraemer.de | http://andrekraemer.de | http://andrekraemer.de/blog | http://github.com/AndreKraemer

Weitere ähnliche Inhalte

Ähnlich wie Performance trotz Entity Framwork

Dojo Und Notes
Dojo Und NotesDojo Und Notes
Dojo Und Notes
dominion
 
JdbcTemplate aus Spring
JdbcTemplate aus SpringJdbcTemplate aus Spring
JdbcTemplate aus Spring
tutego
 

Ähnlich wie Performance trotz Entity Framwork (20)

Back to Basics German 2: Erstellen Sie Ihre erste Anwendung in MongoDB
Back to Basics German 2: Erstellen Sie Ihre erste Anwendung in MongoDBBack to Basics German 2: Erstellen Sie Ihre erste Anwendung in MongoDB
Back to Basics German 2: Erstellen Sie Ihre erste Anwendung in MongoDB
 
Dojo Und Notes
Dojo Und NotesDojo Und Notes
Dojo Und Notes
 
TypeScript
TypeScriptTypeScript
TypeScript
 
Go - Googles Sprache für skalierbare Systeme
Go - Googles Sprache für skalierbare SystemeGo - Googles Sprache für skalierbare Systeme
Go - Googles Sprache für skalierbare Systeme
 
Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)
Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)
Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)
 
JavaScript Performance
JavaScript PerformanceJavaScript Performance
JavaScript Performance
 
Typescript
TypescriptTypescript
Typescript
 
jQuery & CouchDB - Die zukünftige Webentwicklung?
jQuery & CouchDB - Die zukünftige Webentwicklung?jQuery & CouchDB - Die zukünftige Webentwicklung?
jQuery & CouchDB - Die zukünftige Webentwicklung?
 
JdbcTemplate aus Spring
JdbcTemplate aus SpringJdbcTemplate aus Spring
JdbcTemplate aus Spring
 
Einführung in die funktionale Programmierung
Einführung in die funktionale ProgrammierungEinführung in die funktionale Programmierung
Einführung in die funktionale Programmierung
 
Back to Basics – Webinar 2: Ihre erste MongoDB-Anwendung
Back to Basics – Webinar 2: Ihre erste MongoDB-AnwendungBack to Basics – Webinar 2: Ihre erste MongoDB-Anwendung
Back to Basics – Webinar 2: Ihre erste MongoDB-Anwendung
 
Datentransfer mit Oracle Tools
Datentransfer mit Oracle ToolsDatentransfer mit Oracle Tools
Datentransfer mit Oracle Tools
 
Explain explain
Explain explainExplain explain
Explain explain
 
Praesentation TYPO3Camp Berlin Speed mit Extbase
Praesentation TYPO3Camp Berlin Speed mit ExtbasePraesentation TYPO3Camp Berlin Speed mit Extbase
Praesentation TYPO3Camp Berlin Speed mit Extbase
 
Microservices mit Rust
Microservices mit RustMicroservices mit Rust
Microservices mit Rust
 
Datenbankoptimierung für Ruby on Rails
Datenbankoptimierung für Ruby on RailsDatenbankoptimierung für Ruby on Rails
Datenbankoptimierung für Ruby on Rails
 
WiSe 2014 | Softwaretechnologie I _ Funktionen, Zeiger, Strukturen, Bibliotheken
WiSe 2014 | Softwaretechnologie I _ Funktionen, Zeiger, Strukturen, BibliothekenWiSe 2014 | Softwaretechnologie I _ Funktionen, Zeiger, Strukturen, Bibliotheken
WiSe 2014 | Softwaretechnologie I _ Funktionen, Zeiger, Strukturen, Bibliotheken
 
.NET Summit 2016 München: EcmaScript 2015+ with TypeScript
.NET Summit 2016 München: EcmaScript 2015+ with TypeScript.NET Summit 2016 München: EcmaScript 2015+ with TypeScript
.NET Summit 2016 München: EcmaScript 2015+ with TypeScript
 
Dokumentation schreiben kann spass machen
Dokumentation schreiben kann spass machenDokumentation schreiben kann spass machen
Dokumentation schreiben kann spass machen
 
Migrationspfade für Angular 2
Migrationspfade für Angular 2Migrationspfade für Angular 2
Migrationspfade für Angular 2
 

Mehr von André Krämer

Mehr von André Krämer (14)

Xamarin.Forms App in einer Stunde
Xamarin.Forms App in einer StundeXamarin.Forms App in einer Stunde
Xamarin.Forms App in einer Stunde
 
Entwicklung von ASP.NET-Core- und SQL-Server-Anwendungen unter macOS in der P...
Entwicklung von ASP.NET-Core- und SQL-Server-Anwendungen unter macOS in der P...Entwicklung von ASP.NET-Core- und SQL-Server-Anwendungen unter macOS in der P...
Entwicklung von ASP.NET-Core- und SQL-Server-Anwendungen unter macOS in der P...
 
Codewiederverwendung in Xamarin-Apps maximieren
Codewiederverwendung in Xamarin-Apps maximierenCodewiederverwendung in Xamarin-Apps maximieren
Codewiederverwendung in Xamarin-Apps maximieren
 
Einstieg in Xamarin und Xamarin.Forms, DDC 2018
Einstieg in Xamarin und Xamarin.Forms, DDC 2018Einstieg in Xamarin und Xamarin.Forms, DDC 2018
Einstieg in Xamarin und Xamarin.Forms, DDC 2018
 
Xamarin.Forms Workshop, DDC 2018
Xamarin.Forms Workshop, DDC 2018Xamarin.Forms Workshop, DDC 2018
Xamarin.Forms Workshop, DDC 2018
 
Android Apps mit Xamarin entwickeln
Android Apps mit Xamarin entwickelnAndroid Apps mit Xamarin entwickeln
Android Apps mit Xamarin entwickeln
 
Xamarin ohne Mac und Android SDK? - So weit kommen Sie mit dem Xamarin Live P...
Xamarin ohne Mac und Android SDK?- So weit kommen Sie mit dem Xamarin Live P...Xamarin ohne Mac und Android SDK?- So weit kommen Sie mit dem Xamarin Live P...
Xamarin ohne Mac und Android SDK? - So weit kommen Sie mit dem Xamarin Live P...
 
Typische Sicherheitslücken in ASP.NET MVC und Web API Anwendungen
Typische Sicherheitslücken in ASP.NET MVC und Web API AnwendungenTypische Sicherheitslücken in ASP.NET MVC und Web API Anwendungen
Typische Sicherheitslücken in ASP.NET MVC und Web API Anwendungen
 
Lokale Datenhaltung in Xamarin-Apps
Lokale Datenhaltung in Xamarin-AppsLokale Datenhaltung in Xamarin-Apps
Lokale Datenhaltung in Xamarin-Apps
 
HTML5-Performance: So rennt Ihre App und nicht Ihre Anwender (weg)
HTML5-Performance: So rennt Ihre App und nicht Ihre Anwender (weg)HTML5-Performance: So rennt Ihre App und nicht Ihre Anwender (weg)
HTML5-Performance: So rennt Ihre App und nicht Ihre Anwender (weg)
 
Cross Plattform App Entwicklung mit Visual Studio 2015 (Xamarin und Cordova)
Cross Plattform App Entwicklung mit Visual Studio 2015 (Xamarin und Cordova)Cross Plattform App Entwicklung mit Visual Studio 2015 (Xamarin und Cordova)
Cross Plattform App Entwicklung mit Visual Studio 2015 (Xamarin und Cordova)
 
.NET Datenzugriff einfach und performant mit Micro O/R Mappern
.NET Datenzugriff einfach und performant mit Micro O/R Mappern .NET Datenzugriff einfach und performant mit Micro O/R Mappern
.NET Datenzugriff einfach und performant mit Micro O/R Mappern
 
Das Repository-Pattern und der O/R-Mapper: Geniale Kombination oder vergebene...
Das Repository-Pattern und der O/R-Mapper: Geniale Kombination oder vergebene...Das Repository-Pattern und der O/R-Mapper: Geniale Kombination oder vergebene...
Das Repository-Pattern und der O/R-Mapper: Geniale Kombination oder vergebene...
 
Zentrale Dokumentengenerierung mit dem Open XML SDK
Zentrale Dokumentengenerierung mit dem Open XML SDKZentrale Dokumentengenerierung mit dem Open XML SDK
Zentrale Dokumentengenerierung mit dem Open XML SDK
 

Performance trotz Entity Framwork

  • 1. Performance trotz Entity Framework Dipl. Inform. (FH) André Krämer, M. Sc. Softwareentwickler, Trainer & Berater
  • 2.
  • 3. Was machen wir eigentlich den ganzen Tag?
  • 4.
  • 5.
  • 6. ?
  • 8. DataReader (.NET 1.0 Style) using (connection) { SqlCommand command = new SqlCommand( "SELECT CategoryID, CategoryName FROM Categories;", connection); connection.Open(); SqlDataReader reader = command.ExecuteReader(); if (reader.HasRows) { while (reader.Read()) { Console.WriteLine("{0}t{1}", reader.GetInt32(0), reader.GetString(1)); } } else { Console.WriteLine("No rows found."); } reader.Close(); }
  • 10. 30 % der Arbeitszeit sind verloren
  • 11. „if you’re writing ADO.Net code by hand, you’re stealing from your employer or client.” Jeremy D. Miller, 7. November 2008, http://codebetter.com/jeremymiller/2008/11/07/how-to-design-your-data-connectivity-strategy/
  • 13. Bewertung Typed Datasets • Schlechte Performance • Hoher Speicherverbrauch • Geringer Entwicklersupport • Nur bedingt Interoperabel • …
  • 16. OR-Mapper • Abstrahieren die Datenbank für uns • Erlauben einen objektorientierten Zugriff auf die Datenbank • Lassen uns unsere gewohnte Programmiersprache nutzen • „Schützen(?)“ uns davor SQL schreiben zu müssen • Sparen Entwicklungszeit
  • 17. Das Entity Framework macht glücklich! Foto: © Rostislav Sedlacek | Fotolia.com
  • 18. Aber leider nicht Jeden Foto: © Romolo Tavani | Fotolia.com
  • 19. Typische Reaktion des DBA, wenn er sieht, dass Sie das Entity Framework nutzen Foto: © Shakzu | Fotolia.com
  • 20. Ist das Entity Framework wirklich langsam? Foto: © pkruger | istockphoto.com
  • 21. Demo Typische Performancefallen und Lösungen Source Code unter: https://github.com/AndreKraemer/EFPerformanceDemo
  • 22. Allerdings ohne zu raten Foto: © clocki | istockphoto.com
  • 23. Wir messen! Foto: © matt_benoit | istockphoto.com
  • 25. Messen Sie statt zu raten! http://hibernatingrhinos.com/products/EFProf
  • 26. Legen Sie eine ausreichende Menge an realistischen Testdaten an 26http://www.red-gate.com/products/sql-development/sql-data-generator/
  • 27. Laden Sie nicht mehr Daten als benötigt using (var db = new NorthwindDb()) { var products = db.Products; foreach (var product in products) { Console.WriteLine("{0}", product.ProductName); } } SELECT [Extent1].[ProductID] AS [ProductID], [Extent1].[ProductName] AS [ProductName], [Extent1].[SupplierID] AS [SupplierID], [Extent1].[CategoryID] AS [CategoryID], [Extent1].[QuantityPerUnit] AS [QuantityPerUnit], [Extent1].[UnitPrice] AS [UnitPrice], [Extent1].[UnitsInStock] AS [UnitsInStock], [Extent1].[UnitsOnOrder] AS [UnitsOnOrder], [Extent1].[ReorderLevel] AS [ReorderLevel], [Extent1].[Discontinued] AS [Discontinued] FROM [dbo].[Products] AS [Extent1]
  • 28. Laden Sie nicht mehr Daten als benötigt (Lösung) var products = db.Products.Select(p => new {p.ProductName}); foreach (var product in products) { Console.WriteLine("{0}", product.ProductName); } SELECT 1 AS [C1], [Extent1].[ProductName] AS [ProductName] FROM [dbo].[Products] AS [Extent1] 28
  • 29. Laden Sie „Readonly Daten“ nicht in den Change Tracker var shippers = db.Shippers.ToList(); for (int i = 0; i < 200 && i < shippers.Count; i++) { var shipper = shippers[i]; Console.WriteLine("{0} - {1}", shipper.ShipperID, shipper.CompanyName); } var shippers = db.Shippers.AsNoTracking().ToList(); for (int i = 0; i < 200 && i < shippers.Count; i++) { var shipper = shippers[i]; Console.WriteLine("{0} - {1}", shipper.ShipperID, shipper.CompanyName); } 29
  • 30. Laden Sie nur die Zeilen, die Sie wirklich benötigen var shippers = db.Shippers.ToList(); for (int i = 0; i < 10; i++) { Console.WriteLine("{0} - {1}", shippers[i].ShipperID, shippers[i].CompanyName); } var shippers = db.Shippers.Take(10).ToList(); foreach (var shipper in shippers) { Console.WriteLine("{0} - {1}", shipper.ShipperID, shipper.CompanyName); } 30
  • 31. Filtern Sie auf dem Server, nicht auf dem Client var customers = GetCustomers(db).Where(c => c.Country == "Germany"); foreach (var customer in customers) { Console.WriteLine("{0} - {1}", customer.CustomerID, customer.CompanyName); } private IEnumerable<Customers> GetCustomers(NorthwindDb db) { return db.Customers; } var customers = GetCustomersQry(db).Where(c => c.Country == "Germany"); foreach (var customer in customers) { Console.WriteLine("{0} - {1}", customer.CustomerID, customer.CompanyName); } private IQueryable<Customers> GetCustomersQry(NorthwindDb db) { return db.Customers; } 31
  • 32. Lassen Sie sich nicht durch die Intellisense in falsche Richtungen leiten var shippers = db.Shippers.ToList().Take(10); foreach (var shipper in shippers) { Console.WriteLine("{0} - {1}", shipper.ShipperID, shipper.CompanyName); } var shippers = db.Shippers.Take(10).ToList(); foreach (var shipper in shippers) { Console.WriteLine("{0} - {1}", shipper.ShipperID, shipper.CompanyName); } 32
  • 33. Nutzen Sie Find Statt SingleOrDeafault um Entitäten aus dem Cache zu laden var s1 = db.Shippers.SingleOrDefault(c => c.ShipperID == 1); Console.WriteLine("S1: {0} - {1}", s1.ShipperID, s1.CompanyName); var s2 = db.Shippers.SingleOrDefault(c => c.ShipperID == 1); Console.WriteLine("S2: {0} - {1}", s2.ShipperID, s2.CompanyName); var shippers = db.Shippers.Take(10).ToList(); foreach (var shipper in shippers) { Console.WriteLine("{0} - {1}", shipper.ShipperID, shipper.CompanyName); } 33
  • 34. Laden Sie nicht zum Löschen var maxShipperId = db.Shippers.Max(s => s.ShipperID); var shipper = db.Shippers.Find(maxShipperId); db.Shippers.Remove(shipper); db.SaveChanges(); var maxShipperId = db.Shippers.Max(s => s.ShipperID); // db.Shippers.Find(maxShipperId); var shipper = new Shippers {ShipperID = maxShipperId}; db.Shippers.Attach(shipper); db.Shippers.Remove(shipper); db.SaveChanges(); 34
  • 35. Behalten Sie Lazy Loading im Auge var orders = db.Orders.ToList(); foreach (var order in orders) { Console.WriteLine("{0} {1}", order.OrderID, order.Customers.CompanyName); } var orders = db.Orders.Include(o=> o.Customers).ToList(); foreach (var order in orders) { Console.WriteLine("{0} {1}", order.OrderID, order.Customers.CompanyName); } 35
  • 36. Annotieren Sie Ihr Model korrekt (Im Fall von Code First) • public string PreferedCommunication { get; set; } wird zu nvarchar(max) in der Datenbank! • [StringLength(50)] public string PreferedCommunication { get; set; } wird zu nvarchar(50) in der Datenbank modelBuilder.Entity<Customers>() .Property(e=> e.PreferedCommunication) .IsUnicode(false);  varchar statt nvarchar 36
  • 37. Homepage andre@andrekraemer.de | http://andrekraemer.de | http://andrekraemer.de/blog Vielen Dank! Blog Xing Facebook Twitter Google+ 37
  • 38. Sie haben ein Performance oder Speicherproblem in Ihrer Anwendung? Im Rahmen meiner Beratertätigkeit betreue ich seit vielen Jahren Kunden rum um die Themen Datenzugriffsperformance, Anwendungsperformance und Memory Leak Analysen. Kommen Sie bei Bedarf gerne auf mich zu: andre@andrekraemer.de | http://andrekraemer.de 38
  • 39. Meine Dienstleistungen • Schulungen • ASP.NET / JavaScript / AngularJS • Xamarin • Cordova • TX Text Control • Infragistics NetAdvantage • Team Foundation Server • .NET Datenzugriff (Entity Framework, NHibernate, Micro O/R Mapper) • Consulting • Durchführung von Technologieworkshops • Code- / Architekturreviews • Analyse von managed Memory Leaks • Prototypenentwicklung • Remote Entwickler-Support • Projektbegleitendes Coaching • Softwareentwicklung • Mobile Apps (Android, iOS, Windows 10, Windows 8, Windows Phone) • Entwicklung von Web-Anwendungen mit ASP.NET und AngularJS • Entwicklung von Desktop Anwendungen 39andre@andrekraemer.de | http://andrekraemer.de | http://andrekraemer.de/blog | http://github.com/AndreKraemer

Hinweis der Redaktion

  1. Das bedeutet, dass wir in 30 % unserer Arbeitszeit keinen Mehrwert in der Form von Benutzer-Features für unser eigentliches Produkt welches wir entwickeln schaffen können, sondern damit beschäftigt sind Infrastrukturcode zu schreiben. Natürlich ist dies keine wirklich gute Idee, denn Datenzugriff - oder Persistenz - ist ein gelöstes Problem. ..