Entity Framework
Chargement d'entités liées
Recherche…
Remarques
Si les modèles sont correctement associés, vous pouvez facilement charger les données associées à l'aide d'EntityFramework. Vous avez le choix entre trois options: chargement différé, chargement rapide et chargement explicite .
Modèles utilisés dans les exemples:
public class Company
{
public int Id { get; set; }
public string FullName { get; set; }
public string ShortName { get; set; }
// Navigation properties
public virtual Person Founder { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
}
public class Address
{
public int Id { get; set; }
public int CompanyId { get; set; }
public int CountryId { get; set; }
public int CityId { get; set; }
public string Street { get; set; }
// Navigation properties
public virtual Company Company { get; set; }
public virtual Country Country { get; set; }
public virtual City City { get; set; }
}
Chargement paresseux
Le chargement différé est activé par défaut. Le chargement différé est réalisé en créant des classes proxy dérivées et en remplaçant les produits de navigation virtuels. Le chargement paresseux se produit lorsque la propriété est accédée pour la première fois.
int companyId = ...;
Company company = context.Companies
.First(m => m.Id == companyId);
Person founder = company.Founder; // Founder is loaded
foreach (Address address in company.Addresses)
{
// Address details are loaded one by one.
}
Pour désactiver le chargement paresseux pour des propriétés de navigation spécifiques, supprimez simplement le mot-clé virtuel de la déclaration de propriété:
public Person Founder { get; set; } // "virtual" keyword has been removed
Si vous souhaitez désactiver complètement le chargement paresseux, vous devez modifier la configuration, par exemple, dans le constructeur Context :
public class MyContext : DbContext
{
public MyContext(): base("Name=ConnectionString")
{
this.Configuration.LazyLoadingEnabled = false;
}
}
Remarque: n'oubliez pas de désactiver le chargement paresseux si vous utilisez la sérialisation. Les sérialiseurs accédant à toutes les propriétés, vous les chargez tous depuis la base de données. De plus, vous pouvez exécuter une boucle entre les propriétés de navigation.
Chargement rapide
Le chargement rapide vous permet de charger toutes les entités nécessaires à la fois. Si vous préférez que toutes vos entités travaillent sur un même appel de base de données, alors le chargement par Eager est la solution. Il vous permet également de charger plusieurs niveaux.
Vous avez deux options pour charger les entités associées, vous pouvez choisir soit des typologies fortes, soit des surcharges de chaînes de la méthode Include .
Fortement typé.
// Load one company with founder and address details
int companyId = ...;
Company company = context.Companies
.Include(m => m.Founder)
.Include(m => m.Addresses)
.SingleOrDefault(m => m.Id == companyId);
// Load 5 companies with address details, also retrieve country and city
// information of addresses
List<Company> companies = context.Companies
.Include(m => m.Addresses.Select(a => a.Country));
.Include(m => m.Addresses.Select(a => a.City))
.Take(5).ToList();
Cette méthode est disponible depuis Entity Framework 4.1. Assurez-vous d'avoir la référence à l' using System.Data.Entity;
ensemble.
Surcharge de chaîne.
// Load one company with founder and address details
int companyId = ...;
Company company = context.Companies
.Include("Founder")
.Include("Addresses")
.SingleOrDefault(m => m.Id == companyId);
// Load 5 companies with address details, also retrieve country and city
// information of addresses
List<Company> companies = context.Companies
.Include("Addresses.Country");
.Include("Addresses.City"))
.Take(5).ToList();
Chargement explicite
Après avoir désactivé le chargement paresseux, vous pouvez charger des entités paresseusement en appelant explicitement la méthode Load pour les entrées. La référence est utilisée pour charger des propriétés de navigation uniques, tandis que Collection est utilisée pour obtenir des collections.
Company company = context.Companies.FirstOrDefault();
// Load founder
context.Entry(company).Reference(m => m.Founder).Load();
// Load addresses
context.Entry(company).Collection(m => m.Addresses).Load();
Comme sur Eager loading, vous pouvez utiliser les surcharges des méthodes ci-dessus pour charger entiteis par leurs noms:
Company company = context.Companies.FirstOrDefault();
// Load founder
context.Entry(company).Reference("Founder").Load();
// Load addresses
context.Entry(company).Collection("Addresses").Load();
Filtrer les entités associées.
En utilisant la méthode Query , nous pouvons filtrer les entités liées chargées:
Company company = context.Companies.FirstOrDefault();
// Load addresses which are in Baku
context.Entry(company)
.Collection(m => m.Addresses)
.Query()
.Where(a => a.City.Name == "Baku")
.Load();
Requêtes de projection
Si l'on a besoin de données associées dans un type dénormalisé, ou par exemple uniquement un sous-ensemble de colonnes, on peut utiliser des requêtes de projection. S'il n'y a aucune raison d'utiliser un type supplémentaire, il est possible de joindre les valeurs dans un type anonyme .
var dbContext = new MyDbContext();
var denormalizedType = from company in dbContext.Company
where company.Name == "MyFavoriteCompany"
join founder in dbContext.Founder
on company.FounderId equals founder.Id
select new
{
CompanyName = company.Name,
CompanyId = company.Id,
FounderName = founder.Name,
FounderId = founder.Id
};
Ou avec query-syntax:
var dbContext = new MyDbContext();
var denormalizedType = dbContext.Company
.Join(dbContext.Founder,
c => c.FounderId,
f => f.Id ,
(c, f) => new
{
CompanyName = c.Name,
CompanyId = c.Id,
FounderName = f.Name,
FounderId = f.Id
})
.Select(cf => cf);