一 数据对象关系:
先大体说下,数据库模型之间的关系,经典的订单系统,供应商和客户有太多共同信息,我们这里存放在一个表里面:Company, 供应商(company) 和产品之间的关系为N:N, 俗话说:一图胜过千言万语,请看关系图:
二 创建项目:
1. 创建一个空的解决方案,名为:EFInAction;
2. 添加一个Class Library project(类库项目), 名为:EFInAction.Model;
3. 删除class1 文件;
4. 添加一个Unit Test Project, 名为:EFInAction.Test;
三 用database-first(db first) 设计我们的数据实体:
首先创建我们的数据库,数据库生成语句在源码中可以找到;
创建实体:创建实体的过程,大体上可以分成两个部分,第一步:创建实体和复杂实体(complex types),并将它们映射到数据库,第二步:在实体上创建导航属性,并指明实体的外键和关联的表,理论刚开始不能讲的太多,讲太多了也听不明白,一步步跟着做,自然会明白,下面开始创建实体:
1. 在EFInAction.Model中添加一个新项, 选择ADO.NET Entity Data Model;
2. 在弹出的Entity Data Model Wizard, 选择Generate from Database, 点击下一步;
3. 在Choose your data connection 对话框中,点击【new connection】, 弹出Connection properties 对话框
4. 在connection properties 对话框中,选择我们的数据库, 点击【OK】关闭connection properties, 然后勾选上“yes, include the sensitive data…”单选按钮
5. 在弹出的choose your database objects and settings 对话框中勾选上所有的表,然后勾选上”Pluralize or singularize…”复选框,点击【Finish】
6. 这时候会自动打开Model.edmx关系图界面,点击保存,然后会自动生成我们的Model 和 我们的Entity object(在这里是EFInActionEntities,关于这些代码是怎么生成的,可以去参考T4 模板相关知识,这里不讨论),由于我们使用的是EF5.0 所以为自动生成我们的POCO模型(什么是POCO,就是plain-old CLR objects, 就是纯净的Model对象,而不是像EF4.0 时生成的那堆垃圾代码),我们在步骤5的时候,勾选上了一个”Pluralize or singularize…”复选框, 这玩意是干啥的呢,就是在我们的EntityObject 的objectSet对象弄成复数形式,打开你们的Model.Context.cs 文件看看就明白是咋回事了,好了,到这里我们的entity 已经从数据库生成了
7. 由于我们生成的Entity是原生态的,在model里面没有体现出继承的概念,我们还需要对这一部分进行改造(关于EF处理继承,这里先不讲,以后再说),打开Model.edmx文件, 在界面中找到Company 实体,将他干掉(就是删除的意思),这时候会弹出一个提示对话框,问你是不是要删除对应实体的数据库信息,这里选择【NO】(千万注意啊,别选【YES】)
8. 在设计器中,右键选择【Add New】-【Entity】, 在弹出的添加新实体对话框中,按照下图所示填写:
9. 点击【OK】后,设计器中会看到我们刚才添加的实体,在它上面鼠标右键,选择Properties, 在Properties对话框中,将Abstract设为: True;
10. 在Company 实体上再右键选择【Add】-【Scalar Property】,一个新的小框框出现在这个实体中,输入Name, 然后回车;
11. 在你刚刚添加的Scalar Property上面右键属性,在属性窗口中,将Max Length 设为50(这里要和数据库字段的长度对应);
到这里,一个抽象的Company父类就建立完成了(它是Customer 和 Supplier的父类),先歇歇,可能有点晕,没关系你先照着做,以后就会明白的,其实应该也挺好懂的,就是一些关系的建立,接下来我们要创建Customer, Supplier等子类,在创建他们两之前,我们先创建AddressInfo(地址信息),应为无论是Customer, 还是Supplier都有这个属性的,不然快递哥送货就找不到地方了,所以呢他们两可以共用这个类,好开始做,一鼓作气,再而衰,三而竭
13. 在设计器中右键,【Add】-【Complex Type】,这时候会自动打开Model Browser视图,刚添加的Complex Type字段会以高亮显示,把这个字段改为AddressInfo;
14. 然后在AddressInfo 上面右键【Add】-【Scalar Property】- 【String】, 命名为:Address, 将MaxLength 属性设为30;
15. 重复【步骤14】,依次添加City, Country, ZIPCode属性,下图AddressInfo的样子:
现在AddressInfo 和 Company 类型我们都建立完毕了,接下来我们开始创建Customer类:
16. 在设计器中右键属性【Add】-【Entity】 ,在Add Entity对话框中,输入Entity name:Customer,将父类选为Company ,如图:
17. 在Customer 实体上右键【Add】-【Complex Property】,在文本框中输入:BillingAddress,然后打开BillingAddress的属性窗口,将Type改为AddressInfo;
18. 重复步骤17, 添加一个ShippingAddress 属性,然后再添加WSUserName, Password, USEnabled等标量属性
19. 按照步骤16-18 再添加一个Supplier 实体,也给它添加BillingAddress 和 ShippingAddress 复杂属性和PaymentDays, IBAN标量属性,以下是继承关系图:
OK, 我们所有的实体都已经创建完毕了,接下来将我们的实体映射到数据库物理表字段上面
20. 在Company 实体上右键,选择【Mapping Table】,弹出我们的Mapping Table Detail 视图, 在该视图中,左边对应的是物理表字段,右边使我们实体的属性,如果表字段和实体属性名字相同,他们会自动匹配,否则需要我们手动选择;
21. 打开Customer的Mapping Table Detail 视图,选择Company物理表,然后将物理表的简单属性,对应上我们实体的复杂属性,见下图:
22. 点击【Add a Condition】行,选择Type字段,然后在右边对应的框框填写一个大写的C,如图:
23. 在设计器中选择Supplier 实体,右键打开Mapping Table Detail 视图,按照Customer那样,设置对应属性,和条件:见下图:
到这里就把Customer和Supplier这个两个实体搞完鸟,感觉有点费劲啊,第一次做起来可能很麻烦,但是了解这个过程后,就很easy了,接下来我们要处理Product和Shoe, Skirt这个几个实体之间的继承关系,这个东西,没有上面的那么复杂,稍微整下就可以了,开始吧,弄完睡觉去鸟
24. 先把Product 和Skirt, Shoe之间的那根线删掉(Association),
25. 然后在Product实体上面右键,【Add】-【Inheritance】,弹出对话框,将base entity 设为Product,Derived Entity设为Skirt,如下图:
26. 重复步骤 25, 在Shoe上面也加一个Inheritance;
27. 将Shirt的ProductId属性删掉,因为我们已经从Product属性继承了,同样也把Shoe的ProductId删掉;
28. 然后打开Table Mapping Detail视图,将Skirt和Shoe的ProductId映射上;
好,简单的几步就已经将实体弄好了,接下来整他们的关系(relationShip)
29. 鼠标右键Customer 实体,【Add】-【Association】,照着下图填写;
30. 点击【OK】后,在customer 和 Order 之间出现一条线,双击这条线,弹出Referential Constraint对话框(就是主外键对应关系,跟数据库里面一模一样的),看图:
31. 然后在Product 和 Supplier之间建立一个Association,见下图:
32. 在刚才建立的那个Association上面右键选择Table Mapping,将关系映射到物理表ProductSupplier上面,见下图:
四 总结:
大功告成,我们的映射做好了,这时候可能有人要问了,这特么也太费劲了吧,的确是非常费劲,我写的手都酸了,应为我们这里展示了Entity Framework 在处理对象继承的问题,所以需要这样,如果你的项目没有类似这样的继承关系的话,那么你直接从数据库里面生成实体,就可以满足要求了,不用这样麻烦的配来配去。
也不要感到困惑,我们刚才配的这些,完全是在告诉Entity Framework 我们的实体之间是怎么个对应关系,你可以用Xml Editor 打开model.edmx文件先瞅瞅,全部都是一些XML,如果用过Hibernate的就应该很清楚了,关于EDMX文件的一些节点,我会在以后讲解。
这一章是对数据环境的配置问题,如果你们觉得麻烦,可以直接把我的源代码拷过去,这些配置在你慢慢使用Entity Framework的时候,想不明白都难