Cet article présente principalement en détail la mise en œuvre générale des effets de pagination personnalisés, des ajouts, des suppressions et des modifications basés sur Entity Framework. Il a une certaine valeur de référence. Les amis intéressés peuvent s'y référer
Introduction<.>
J'ai déjà écrit une implémentation de pagination basée sur Dapper, et maintenant j'écrirai une implémentation de pagination basée sur Entity Framework, ainsi qu'une implémentation universelle d'ajouts, de suppressions et de modifications.
Code
Commençons par le code : https://github.com/jinweijie/EF.GenericRepository
Comment exécuter l'exemple
comme avant :
1 Clonez d'abord le code et décompressez Database.7z dans Database
2. SQL Server LocalDB. Si vous n'utilisez pas LocalDB de SQL Server, vous devez modifier la chaîne de connexion dans App.Config.
3. Ctrl + F5, exécutez l'exemple de programme.
Classe de base du référentiel - requête
CommonAbstractRepository.cs est la classe de base du référentiel, qui implémente l'ajout, la suppression , modification et requête. Certaines méthodes, telles que :
public virtual Tuple<IEnumerable<T>, int> Find(Expression<Func<T, bool>> criteria
, int pageIndex
, int pageSize
, string[] asc
, string[] desc
, params Expression<Func<T, object>>[] includeProperties)
Copier après la connexion
Cette méthode est l'une des méthodes de requête AbstractRepository et est utilisée pour personnaliser les requêtes de pagination, où le critère est un expression comme les Conditions de requête, les paramètres pageIndex, pageSize, asc, desc sont des paramètres liés à la pagination
Concernant plusieurs tables (tables associées) :
includeProperties est la table associée à Join lorsqu'il y en a plusieurs tableaux. Étant donné que la valeur par défaut d'EF est Lazy Loading, les tables associées ne sont pas chargées immédiatement par défaut. Ainsi, parfois, si vous ne faites pas attention lors de l'écriture du code, vous pouvez parcourir n tables de mots dans une boucle for. Utilisez le paramètre includeProperties pour rejoindre la table associée lors de la requête.
Classe de base du référentiel - ajout, suppression et modification
AbstractRepository a implémenté les méthodes d'ajout, de suppression et de modification à l'aide de génériques :
public virtuel T Créer (entité T)
public virtuel T Update (entité T)
public virtuel T CreateOrUpdate (entité T)
public virtuel vide Supprimer (TId id)
Dans De plus, à propos de l'implémentation de la transaction, j'ai utilisé le mode Unité de travail, plusieurs référentiels partagent un DBContext, à propos de l'UOW, veuillez le trouver dans CommonUnitOfWork.cs.
Lors de l'appel d'UOW, cela ressemble fondamentalement à ceci :
var uow = new EFUnitOfWork();
var repo = uow.GetLogRepository();
repo.Create(new Log
{
LevelId = 1,
Thread = "",
Location = "Manual Creation",
Message = "This is manually created log.",
CreateTime = DateTimeOffset.Now,
Date = DateTime.Now
});
uow.Commit();
Copier après la connexion
Obtenez un ou plusieurs référentiels depuis UnitOfWork, partagez DBContext et ajoutez, supprimez , et modifier l'opération, et enfin uow unifie SaveChanges.
Classes dérivées de Repository
Comme il existe déjà AbstractRepository, de nombreuses méthodes d'ajout, de suppression, de modification et de vérification sont implémentées, donc les classes dérivées, telles que LogRepository dans l'exemple de projet Cela peut fondamentalement devenir très simple, en implémentant principalement une logique métier spécifique. Dans l'exemple de projet, comme il n'y a pas de logique métier particulière, ce sera très simple :
.
public class LogRepository : AbstractRepository<Log, int>
{
public LogRepository(EFContext context)
: base(context)
{
}
}
Copier après la connexion
À propos de la génération d'entités
Je préfère l'implémentation Database First. Je conçois d'abord la base de données, puis j'utilise l'ingénierie inverse edmx pour générer POCO. Vous pouvez vous référer aux fichiers pertinents dans le répertoire Entity.
Bien sûr, si vous aimez Code First, il n'y a aucun problème et la mise en œuvre de cet article s'applique toujours.
Utilisez Logging pour suivre EF SQL
Lors de l'utilisation d'Entity Framework, il est préférable de faire attention au SQL généré par EF, afin qu'il puisse être découvert pendant la phase de développement Certains problèmes de performances potentiels peuvent éviter d'être submergés dans l'environnement de production :)
Dans CommonEFContext.cs, il existe un élément de configuration EnableTraceSql. Si c'est vrai, alors le SQL généré par EF sera. enregistré par nlog. J'ai configuré les journaux nlog dans la base de données. C'est-à-dire que lorsque vous exécutez l'exemple de projet, chaque fois que vous effectuez une requête, un nouvel enregistrement de journal sera ajouté et le contenu est le SQL généré lors de la requête :
Modèle de spécification
Dans la méthode de requête, il existe une surcharge qui accepte un exemple ISpecification. Cette implémentation peut contrôler efficacement la logique métier pour les interfaces écrites pour être appelées par d'autres. vous pouvez déterminer clairement les paramètres de requête, par exemple :
public class LogSearchSpecification : ISpecification<Log>
{
public string LevelName { get; set; }
public string Message { get; set; }
public Expression<Func<Log, bool>> ToExpression()
{
return log => (log.Level.Name == LevelName || LevelName == "") &&
(log.Message.Contains(Message) || Message == "");
}
public bool IsSatisfiedBy(Log entity)
{
return (entity.Level.Name == LevelName || LevelName == "") &&
(entity.Message.Contains(Message) || Message == "");
}
}
Copier après la connexion
Ensuite, le code qui appelle cette méthode de requête peut clairement savoir que mes conditions de requête sont LevelName et Message. Quant à LevelName Is égal à et Message is Like sont implémentés dans LogSearchSpeficiation, obtenant une bonne encapsulation.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!