Hoe werkt het entiteitsraamwerk voor een groot aantal records?

Ik zie al een onbeantwoorde vraag hier op.

Mijn vraag is –

Is EF echt klaar voor grote toepassingen?

De vraag kwam voort uit deze onderliggende vragen –

  1. EF haalt alle records in het geheugen en voert vervolgens de query uit
    operatie. Hoe zou EF zich gedragen als de tabel ongeveer ~1000 records heeft?
  2. Voor een eenvoudige bewerking moet ik het record eruit halen, het bewerken en
    druk vervolgens naar db met SaveChanges()

Antwoord 1, autoriteit 100%

Ik kreeg te maken met een vergelijkbare situatie waarin we een grote database hadden met veel tabellen van 7-10 miljoen records elk. we gebruikten het Entity-framework om de gegevens weer te geven. Om mooie prestaties te krijgen, heb ik dit geleerd; Mijn 10 gouden regels voor Entity Framework:

  1. Begrijp dat het aanroepen van de database alleen wordt gedaan wanneer de daadwerkelijke records vereist zijn. alle bewerkingen worden alleen gebruikt om de query (SQL) te maken, dus probeer slechts een stukje gegevens op te halen in plaats van een groot aantal records op te vragen. Knip de ophaalmaat zo veel mogelijk af

  2. Ja, (in sommige gevallen zijn opgeslagen procedures een betere keuze, ze zijn niet zo slecht als sommigen je doen geloven), waar nodig moet je opgeslagen procedures gebruiken. Importeer ze in uw model en voer er functie-imports voor uit. U kunt ze ook rechtstreeks ExecuteStoreCommand(), ExecuteStoreQuery<>() aanroepen. Hetzelfde geldt voor functies en views, maar EF heeft een heel vreemde manier om functies “SELECT dbo.blah(@id)” aan te roepen.

  3. EF werkt langzamer wanneer het een entiteit met een diepe hiërarchie moet vullen. wees uiterst voorzichtig met entiteiten met een diepe hiërarchie

  4. Soms, als je records opvraagt ​​en je bent niet verplicht om ze te wijzigen, moet je EF vertellen de eigenschapswijzigingen niet te bekijken (AutoDetectChanges). op die manier is het ophalen van records veel sneller

  5. Indexering van database is goed, maar in het geval van EF wordt het erg belangrijk. De kolommen die u gebruikt voor het ophalen en sorteren, moeten correct zijn geïndexeerd.

  6. Als je model groot is, wordt de modelontwerper van VS2010/VS2012 echt gek. dus verdeel uw model in middelgrote modellen. Er is een beperking dat de entiteiten van verschillende modellen niet kunnen worden gedeeld, ook al verwijzen ze mogelijk naar dezelfde tabel in de database.

  7. Als u wijzigingen moet aanbrengen in dezelfde entiteit op verschillende plaatsen, gebruik dan dezelfde entiteit, breng wijzigingen aan en sla deze slechts één keer op. Het punt is om te VERMIJDEN hetzelfde record op te halen, wijzigingen aan te brengen & sla het meerdere keren op. (Tip voor echte prestatiewinst).

  8. Als je de informatie in slechts één of twee kolommen nodig hebt, probeer dan niet de volledige entiteit op te halen. je kunt je sql rechtstreeks uitvoeren of iets hebben met een mini-entiteit. Mogelijk moet u ook enkele veelgebruikte gegevens in uw applicatie cachen.

  9. Transacties zijn traag. wees voorzichtig met ze.

  10. SQL Profiler of een andere queryprofiler is je vriend. Voer het uit bij het ontwikkelen van uw applicatie om te zien wat EF naar de database stuurt. Wanneer je een join uitvoert met LINQ- of Lambda-expressie in je applicatie, genereert EF meestal een Select-Where-In-Select-stijlquery die niet altijd goed presteert. Als je een dergelijk geval vindt, steek dan je mouwen op, voer de join uit op DB en laat EF de resultaten ophalen. (Ik ben deze vergeten, de belangrijkste!)

Als je deze dingen in gedachten houdt, zou EF bijna dezelfde prestaties moeten leveren als gewone ADO.NET, zo niet hetzelfde.


Antwoord 2, autoriteit 14%

1. EF haalt alle records in het geheugen en voert vervolgens de querybewerking uit. Hoe zou EF zich gedragen als de tabel ongeveer ~1000 records heeft?

Dat is niet waar!EF haalt alleen noodzakelijke records op en query’s worden omgezet in juiste SQL-instructies. EF kan objecten lokaal cachen binnen DataContext(en alle wijzigingen in entiteiten volgen), maar zolang je de regel volgt om de context alleen open te houden wanneer dat nodig is, is dat geen probleem.

2. Voor een eenvoudige bewerking moet ik het record eruit halen, het bewerken en vervolgens naar db pushen met SaveChanges()

Het is waar, maar Ik zou niet de moeite nemenom dat te doen, tenzij je echt de prestatieproblemen ziet. Omdat 1. niet waar is, wordt er slechts één record uit DB opgehaald voordat het wordt opgeslagen. U kunt dat omzeilen door de SQL-query als een tekenreeks te maken en deze als een gewone tekenreeks te verzenden.


Antwoord 3, autoriteit 5%

  1. EF vertaalt uw LINQ-query naar een SQL-query, zodat niet alle records in het geheugen worden opgehaald. De gegenereerde SQL is misschien niet altijd de meest efficiënte, maar duizend records is geen enkel probleem.
  2. Ja, dat is een manier om het te doen (ervan uitgaande dat je maar één record wilt bewerken). Als u meerdere records wijzigt, kunt u ze allemaal verkrijgen met één query en SaveChanges()zal al die wijzigingen behouden.

Antwoord 4, autoriteit 4%

EF is geen slecht ORM-framework. Het is een andere met zijn eigen kenmerken. Vergelijk Microsoft Entity Framework 6 met bijvoorbeeld NetTiers, dat wordt aangedreven door Microsoft Enterprise Library 6.

Dit zijn twee totaal verschillende beesten. Het geaccepteerde antwoord is echt goed omdat het de nuances van EF6 doorloopt. Het belangrijkste om te begrijpen is dat elke ORM zijn eigen sterke en zwakke punten heeft. Vergelijk de projectvereisten en de bijbehorende patronen voor gegevenstoegang met de gedragspatronen van de ORM.

Bijvoorbeeld: NetTiers geeft u altijd hogere onbewerkte prestaties dan EF6. Maar dat komt vooral omdat het geen ORM is met aanwijzen en klikken en als onderdeel van het genereren van de ORM optimaliseert u uw datamodel, voegt u waar relevant aangepaste opgeslagen procedures toe, enz… als u uw datamodel met dezelfde inspanning voor EF6 zou je waarschijnlijk in de buurt komen van dezelfde prestatie.

Overweeg ook of u de ORM kunt wijzigen? met NetTiers kunt u bijvoorbeeld extensies toevoegen aan de codesmith-sjablonen om uw eigen ontwerppatronen op te nemen bovenop wat wordt gegenereerd door de basis ORM-bibliotheek.

Overweeg ook dat EF6 veel gebruik maakt van reflectie, terwijl NetTiers of een bibliotheek die wordt aangedreven door Microsoft Enterprise Library, in plaats daarvan veel gebruik zal maken van Generics. Dit zijn twee totaal verschillende benaderingen. Waarom? Omdat EF6 is gebaseerd op dynamische reflectie, terwijl NetTiers is gebaseerd op statische reflectie. Wat sneller en beter is, hangt volledig af van de gebruikspatronen die van de ORM worden vereist.

Soms werkt een hybride aanpak beter: denk bijvoorbeeld aan EF6 voor Web API OData-eindpunten, een paar grote tabellen verpakt met NetTiers & Microsoft Enterprise Library met aangepaste opgeslagen procedures en een paar grote masterdata-tabellen verpakt met een op maat gemaakte write-through-objectcache waarbij de recordset bij het eerste laden naar de geheugencache wordt gestreamd met behulp van een ADO-gegevenslezer.

Deze zijn allemaal verschillend en hebben allemaal hun best passende scenario’s: EF6, NetTiers, NHibernate, Wilson OR Mapper, XPO van Dev Express, enz…


Antwoord 5, autoriteit 3%

Er is geen eenvoudig antwoord op uw vraag. Het belangrijkste is wat u met uw gegevens wilt doen? En heb je zoveel data tegelijk nodig?

EF heeft uw query’s naar SQL vertaald, dus op dit moment is er geen object in het geheugen. Wanneer u de gegevens krijgt, bevinden de geselecteerde records zich in het geheugen. Als je een groot aantal grote objecten selecteert, kan het een prestatiemoordenaar zijn als je ze allemaal moet manipuleren.

Als u ze niet allemaal hoeft te manipuleren, kunt u het bijhouden van wijzigingen uitschakelen en later inschakelen voor afzonderlijke objecten die u moet manipuleren.

Dus je ziet dat het afhangt van je type applicatie.
Als u een massa gegevens efficiënt moet manipuleren, gebruik dan geen OR-Mapper!

Anders is EF prima, maar bedenk hoeveel objecten je echt tegelijk nodig hebt en wat je ermee wilt doen.

Other episodes