[ASP.NET
MVC The Road to Mavericks] 06 - Utilisation d'Entity Framework
C'est normal d'être inactif à la maison, continuons à écrire ma série [ASP.NET MVC The Road to Mavericks] . Dans le billet de blog précédent de cette série, lors de l'affichage de la liste d'informations sur le livre, nous avons créé manuellement les données dans le code du programme. Cet article montrera comment utiliser Entity
Framework dans ASP.NET MVC pour obtenir des données de la base de données. Bien que le titre de cet article semble relativement simple, si vous le lisez attentivement, je pense que vous y gagnerez certainement quelque chose.
Répertoire de cet article :
ORM et EF
Quand on veut développer une application, il faut réfléchir à la manière d'afficher les données et comment conserver les données. Lorsque nous examinons ce problème, la chose la plus importante dont nous devons nous soucier est la performance du programme, la facilité de développement, ainsi que la maintenabilité et l'évolutivité du code.
La persistance fait référence à un mécanisme qui peut enregistrer de manière permanente diverses informations sur l'état du traitement dans une application. S'il n'y a pas de mécanisme de persistance, l'état ne peut être sauvegardé qu'en mémoire et sera perdu à l'arrêt de la machine.
Dans les applications, lorsque l'on souhaite sauvegarder des données de manière permanente, on choisit une base de données relationnelle (Relation DataBase) ; lorsque l'on souhaite sauvegarder des données temporairement, on utilise des objets stockés en mémoire. Actuellement, la plupart des développeurs utilisent la technologie des bases de données relationnelles comme mécanisme de persistance. Bien que certaines personnes essaient désormais d'utiliser la technologie des bases de données objets (Object DataBase), la technologie des bases de données relationnelles restera le principal mécanisme de persistance pendant de nombreuses années.
Pourquoi la base de données d'objets apparaît-elle ? Le langage SQL est un langage interprété non procédural, orienté ensemble, tandis que de nombreux langages de haut niveau sont des langages compilés procéduraux, orientés objet, ce qui crée une inadéquation entre les deux langages, ce qui entraîne une efficacité insatisfaisante. Cette inadéquation est appelée « inadéquation d'impédance », et la base de données d'objets semble résoudre la « inadéquation d'impédance ».
Nous savons que dans la technologie des bases de données relationnelles, Table est utilisée pour stocker et organiser les données dans une structure de lignes et de colonnes. Avant .NET 2.0, lorsque C# n'avait pas de génériques, les utilisateurs utilisaient essentiellement des DataTables remplis de DataSets pour mapper et stocker les données interrogées à partir de bases de données relationnelles, comme le montre le code suivant :
using (SqlConnection conn = new SqlConnection(connString)) { using (SqlDataAdapter da = new SqlDataAdapter("Select * from order", conn)) { DataTable dt = new DataTable(); da.Fill(dt); ... } }
Bien que cette méthode autorise les objets Langages orientés pour correspondre aux bases de données relationnelles, il présente des défauts évidents, tels que la sécurité de non-type, des difficultés de manipulation et de faibles performances. À partir de .NET 2.0, les gens ont commencé à utiliser des collections d'objets de modèle d'entité pour faire correspondre les données dans des bases de données relationnelles grâce à une technologie générique. Cette méthode a résolu les lacunes rencontrées par la méthode DataTable, et elle a un typage fort, une complétion automatique dans VS, au moment de la compilation. la vérification et d'autres fonctionnalités le rendent populaire parmi les développeurs .Net.
Afin d'éviter aux développeurs d'avoir à effectuer ce travail de "matching" manuellement, de nombreux outils ORM (tels que Entity Framework, NHibernate, etc.) ont été développés. Outil ORM (Object Relation Mapping), comme son nom l'indique, son rôle est de résoudre le « décalage » entre « relation » et « orienté objet ». Il permet aux développeurs de passer plus de temps sans trop prêter attention à la couche de persistance. Concentrez-vous sur les affaires.
Entity Framework (EF) est une solution ORM développée par Microsoft basée sur ADO.NET, principalement basée sur Entity Data Model (EDM). EF utilise la méthode d'abstraction des structures de données pour convertir chaque objet de base de données en un objet de classe (Entité) dans l'application, tandis que les champs de données sont convertis en attributs (Propriété) et les relations sont converties en attributs d'association (Association), de sorte que Le modèle E/R
de la base de données est entièrement converti en modèle objet, afin que les développeurs puissent utiliser des langages de programmation orientés objet familiers pour appeler et accéder. EF 4.0 et versions ultérieures prendront en charge trois modes de génération : Database First, Model First et Code First. Le mode Code First est utilisé par un plus grand nombre de personnes.
Je ne parlerai pas beaucoup de concepts et de choses théoriques. J'ai également recherché des ressources en ligne avec des questions et je les ai résumées en fonction de ma propre compréhension. Et je n'ai pas de talent pour décrire. mais je ne peux pas savoir comment organiser le langage.
Le but de cet article est principalement de permettre aux lecteurs d'avoir une compréhension perceptuelle d'EF, puis de comprendre l'application d'EF dans ASP.NET MVC. Je n'étudierai pas les choses théoriques, je présenterai EF séparément la prochaine fois. .
Utilisation d'Entity Framework
Suite au billet de blog précédent [ASP.NET
MVC Mavericks Road] 05 - En utilisant Ninject, nous devons maintenant modifier les données créées à la main dans le code en Lire à partir de la base de données. Pour ce faire, nous préparons d’abord la base de données. Cet exemple utilise MS SQL Server, mais il en va de même pour d'autres bases de données. Créez d'abord une base de données nommée BookShop, puis exécutez le script suivant pour créer une table Books :
CREATE TABLE Books ( [ID] INT NOT NULL PRIMARY KEY IDENTITY, [Title] NVARCHAR(100) NOT NULL, [Isbn] VARCHAR(20) NOT NULL, [Summary] NVARCHAR(1000) NOT NULL, [Author] NVARCHAR(50) NOT NULL, [Thumbnail] VARBINARY(MAX), [Price] DECIMAL(16, 2) NOT NULL, [Published] DATE NOT NULL, )
然后随便在表中加几条用于测试的数据:
接下来我们就要让应用程序连接数据库了。由于上一篇博文是我在公司用休息的时间写的,公司的电脑装的是VS2010,家里的笔记本装的是VS2012,所以得重新把上篇博文的示例移到VS2012上,对于本示例,VS2010和VS2012都是一样的。上一篇示例项目的目录结构如下:
本文的示例将在上篇的这个示例基础上继续。
用NuGet在BookShop.Domain工程中安装Entity Framework包,方法请参考本系列的上一篇文章。
在BookShop.Domain工程的Concrete文件夹中添加一个名为EFDbContext的类,代码如下:
public class EFDbContext : DbContext { public DbSet<Book> Books { get; set; } }
使用EF Code First第一步就是创建一个继承自System.Data.Entity.DbContext的类,这个类将为数据库中的每个表定义一个属性,属性的名称代表数据库中的表名。DbSet作为返回类型,它是用于生成CRUD(Create、Read、Update和Delete)操作的装置,映射数据库表的行。
我们需要在BookShop.WebUI工程中的web.config配置文件中添加数据库的连接字符串,来告诉EF怎样连接数据库。根据自己机器上的数据库配置连接字符串如下:
<connectionStrings> <add name="EFDbContext" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=BookShop;User ID=sa;Password=sa" providerName="System.Data.SqlClient" /> </connectionStrings>
接下来,我们把BookShop.Domain工程下Concrete文件中的BookRepository类文件改造一下,把代码中手工造的数据改成从数据库读取,以测试应用程序是否可以正常连接数据库。修改后的BookRepository类如下:
public class BookRepository : IBookRepository { private EFDbContext context = new EFDbContext(); public IQueryable<Book> Books { get { return context.Books; } } }
在我们的这个仓储类中,我们改使用EF,通过创建一个EFDbContext类的实例来获取数据库中的数据。如你所见,我们不需要自己写ADO.NET代码去连接和读取数据库,非常简洁明了,我们就是这样使用Entity Framework的。我们来看一下运行效果吧:
到这我们已经成功使用EF连接上了数据库,并从数据库中读取出来了数据。我们还可以通过Linq进行非常灵活的查询,就像写SQL一样。比如要查询价格在100元以下的前10条记录,并且按价格从低到高显示,那么我们可以在BookShop.WebUI工程下的BookController中的List方法中这样写:
public ViewResult List() { return View(repository.Books .OrderBy(b => b.Price) .Where(b => b.Price < 100) .Take(10)); }
或许你很快就会对EF获取数据库的方式产生这样的疑问:EF从数据库中读取整个Books表的数据到内存,然后返回给调用者(上面代码中的repository.Books)用Linq语句过滤用户想要的前10条数据,如果Books表中有几百万条数据,那内存岂不是完蛋了,EF不会这么傻吧?EF会不会根据Linq查询语句智能地生成SQL文本再到数据库中去查询数据呢?这里就要讲讲IQueryable和IEnumerable了。
IQueryable 和 IEnumerable
其实,对于上面的即有过虑又有排序的条件查询Linq语句,EF是读取数据库中整个Books表中的数据到内存,还是根据Linq查询语句智能的生成SQL再执行查询,完全编码者来决定的。我们打开BookShop.Domain工程的BookRepository类文件,请注意该类中Books属性的返回类型:
... public IQueryable<Book> Books { get { return context.Books; } }
我们对使用IQueryable作为返回类型提了个疑问:为什么用IQueryable而不用IEnumerable作为返回类型?答案是:使用IQueryable,EF会根据调用者的Linq表达式先生成相应的SQL查询语句,然后到数据库中执行查询,查询出来的数据即是用户想要的数据;而使用IEnumerable,Linq表达式的过滤、排序等操作都是在内存中发生的,即EF会先从数据库中把整个表的数据查询出来放在内存中,然后由调用者使用Linq语句进行过滤、排序等操作。是不是这样呢?我们来监视一下两种情况EF生成的SQL语句就知道了。
我们先来看看使用IQueryable的情况。重新运行一下程序,然后使用SQL Server Management Studio的活动和监视器查看一下我们的BookShop应用程序所执行的SQL语句,结果如下:
结果证明使用IQueryable,EF是先根据Linq表达式生成相应的SQL语句再执行查询的。
我们再稍稍修改一下代码来看看用IEnumerable的情况。把BookRepository类修改如下:
public class BookRepository : IBookRepository { private EFDbContext context = new EFDbContext(); public IEnumerable<Book> Books { get { return context.Books; } } }
当然BookRepository类所实现的IBookRepository接口(在BookShop.Domain工程的Abstract文件夹中)也要改一下:
public interface IBookRepository { IEnumerable<Book> Books { get; } }
再重新运行一下应用程序,用活动和监视器查看最后执行的SQL语句如下图:
我们看到改用IEnumerable后,EF生成的SQL没有任何过滤、排序等的操作,它一次把表中的所有数据都Select出来,和上面写的Linq表达式一点都没关系。
IQueryable虽然可以很智能地根据Linq表达式生成相应的SQL语句,但毕竟有一个分析Linq表达式的过程,相对来说性能比IEnumerable要差。那么我们什么时候用IEnumerable,什么时候用IQueryable呢?我想,对于少量的数据(比如从数据库中读取应用程序相关的系统信息)和不需要对数据进行过滤操作的情况,用IEnumerable比较适合;对于数据量较大需要对数据进行过滤(比如分页查询)的情况,则用IQueryable比较合适。
以上就是[ASP.NET MVC 小牛之路]06 - 使用 Entity Framework的内容,更多相关内容请关注PHP中文网(www.php.cn)!