原文鏈接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pattern-and-dep/ 系列目錄: Relationship in Entity Framewo ...
系列目錄:
- Relationship in Entity Framework Using Code First Approach With Fluent API【【使用EF Code-First方式和Fluent API來探討EF中的關係】】
- Code First Migrations with Entity Framework【使用EF 做資料庫遷移】
- CRUD Operations Using Entity Framework 5.0 Code First Approach in MVC【在MVC中使用EF 5.0做增刪查改】
- CRUD Operations Using the Repository Pattern in MVC【在MVC中使用倉儲模式,來做增刪查改】
- CRUD Operations Using the Generic Repository Pattern and Unit of Work in MVC【在MVC中使用泛型倉儲模式和工作單元來做增刪查改】
- CRUD Operations Using the Generic Repository Pattern and Dependency Injection in MVC【在MVC中使用泛型倉儲模式和依賴註入,來做增刪查改】
這篇文章,我將介紹如何在MVC項目中,使用泛型倉儲模式和依賴註入實現增刪查改。
這篇文章的章節如下:
1.介紹【Introduction】
2.依賴倒置原則(DIP)【Dependency Inversion Principle】
a.真實的例子【Real-Life Example】
b.實際不使用依賴倒置(DIP)的例子【Practical Example without DIP】
c.實際使用依賴倒置(DIP)的例子【Practical Example with DIP】
3.控制反轉(IOC)模式【Inversion of Control (IoC) Pattern】
4.依賴註入(Dependency Injection)【DI】
a.緊耦合【Tight Coupling】
b.松耦合【Loose Coupling】
5.依賴註入的容器【Dependency Injection (DI) Container】
6.程式增刪查改的設計步驟【CRUD operations Application Design】
a.在程式中定義實體【Define Entities in Application】
b.定義數據上下文【Define Context Class】
c.定義映射實體類【Define Mapping of Entities】
d.創建泛型倉儲【Create Generic Repository】
e.創建服務來對用戶表進行操作【Create Service for User Operations】
7.在MVC程式中使用IOC和DI【An MVC Application Using the IoC and DI】
a.引入Ninject依賴註入容器【Ninject Dependency Injection Container】
b.用於增刪查改的Model和控制器【 CRUD Operations Model and Controller】
c.create/Edit視圖【reate / Edit User View】
d.User List視圖【User List View】
e.User Detail視圖【User Detail View】
f.Delete User視圖【Delete User】
8.總結【Conclusion】
9.下載【Download】
介紹
A software developer writes a lot of code that is tightly coupled and when complexity grows the code will eventually deteriorate into spaghetti code, in other words application design being a bad design. A bad design that has one of the following causes.
deteriorate [ 英 [dɪ'tɪərɪəreɪt] 美 [dɪ'tɪrɪəret] vi. 惡化,變壞 vt. 惡化]
spaghetti 【 英 [spə'getɪ] 美 [spə'ɡɛti] n. 義大利式細麵條】
翻譯:一個軟體開發者寫出了很多緊耦合的代碼,然而當代碼變的很複雜的時候,他寫的代碼就會惡化成義大利麵條(不堪一擊),換句話說程式就變成了一個不好的設計,一個不好的設計是由下麵幾種因素導致的:
1.Rigid: A design is rigid if it cannot be easily changed. A single change is heavily dependent on another module so this change causes a cascade of changes that couldn't be predicted, the impact of change could not be estimated.
2.Fragile: A simple change to one part of the application leads to failures in another part of it that appears completely unrelated. Fixing those problems leads to even more problems.
3.Immobile: When the desirable parts of the design are highly dependent upon other details that are not desired and that is why one part of the application could not be used in another application.
Rigid 【 英 ['rɪdʒɪd] 美 ['rɪdʒɪd] adj. 嚴格的;僵硬的,死板的;堅硬的;精確的】
Fragile 【 英 ['frædʒaɪl] 美 ['frædʒəl] adj. 脆的;易碎的】
Immobile 【 英 [ɪ'məʊbaɪl] 美 [ɪ'mobl] adj. 固定的;穩定的;不變的】
翻譯:
1.死板的:如果設計是死板的,那麼想要改變就很難了。一個小小的改變就會牽制很多其他的模塊,所以這樣的改變就會導致一連串不能預期的改變,並且這個改變所帶來的影響是不能預估的。
2.易碎的:程式中一個簡單的改變,就會導致其他不想關的部分完全癱瘓。修複這些問題甚至會導致更多的問題。
3.固定的:當程式設計中的比較好的部分組件緊緊耦合,其他我們不想提取出來的組件的時候,這個時候這個設計比較好的組件就很難重用到其他的項目中了。
The Dependency Inversion Principle is a solution for all these causes, that's why in this article I explain it. This article basically focuses on DIP, IoC, DI and DI containers so before diving into these, I just want to provide a small introduction in this section.
翻譯:依賴註入原則就是解決上面這些問題的一個很好的解決方案。這也是我為什麼要在這篇文章中詳細解釋的原因。這篇文章基礎性了講解依賴倒置原則,控制反轉容器和依賴註入,所以在講解這些之前,我打算先來一個簡單的介紹。
The Dependency Inversion Principle (DIP) is a software design principle that is the last principle of SOLID while Inversion of Control (IoC) is a software design pattern. Here I used two terms, one is a principle and the other is a pattern. So what is the basic difference between these?
翻譯: 依賴倒置原則是設計原則中最後一個。然後控制反轉是軟體的設計模式。這裡我使用這兩個術語,一個是設計原則另外一個是設計模式。那麼他們之間基本的區別是什麼呢?
1. Software Design Principle: Software Design Principles represent a set of guidelines that help us to avoid having a bad design. These are less about specific languages or paradigms and more generally "Don't Repeat Yourself" (DRY); the DRY principle is true for all programming.
翻譯:軟體設計原則:軟體設計原則也就是一系列幫助我們避免不好的軟體設計方針。設計原則,很少是關聯到具體的編程語言或者編程範式的,更多的是關係到“不要重覆你自己”,軟體設計原則對所有的語言編程都是同樣有效的。
2. Software Design Pattern: Software Design Patterns are a general reusable solution to a commonly occurring problem within a given context in software design. These are common solutions for object-oriented programming problems. Like the Singleton Pattern and Factory Pattern.
翻譯:軟體設計模式:軟體設計模式:軟體設計模式通常是給出,在既定的環境中普遍存在的問題的,一個可以重用的解決方案。軟體設計模式是解決在面向對象編程過程中出現的問題的一個很通用的解決方案,例如:單例模式和工廠模式。
依賴倒置原則
It is the fifth principle of SOLID where “D” stands for Dependency Inversion Principle. Its main goal is decoupling software modules, in other words software design should be loosely coupled instead of tightly coupled.
翻譯:依賴倒置原則是設計原則中的第五個,D代表依賴倒置原則。它的主要目標是去除軟體設計模塊之間的耦合性,換句話說軟體設計,應該是松耦合的而不是緊耦合的。
The principle states:【依賴倒置原則的特征】
1.High-level modules should not depend upon low-level modules. Both should depend upon abstractions.【高層次的模塊不應該依賴於低層次的模塊,兩者都應該依賴於抽象層。】
2.Abstractions should not depend upon details. Details should depend upon abstractions.【抽象層不應該依賴於具像層,具像層應該依賴於抽象層。】
In short the higher-level module defines an interface and lower-level module implements that interface. To explain this sentence we use a real-life example.【換句話說,高層次的模塊定義了一個介面,然後低層次的模塊實現了這個介面,為瞭解釋這個場景我使用了一個真實的例子。】
真實的例子
Suppose you are sitting on your desk. Your desk has some gadgets, like your development machine (LCD Monitor or Laptop) and mobile phone. The LCD Monitor has a cable that connects from the electric port (power cable) and the same as the mobile phone that also has a charging cable that also connects to an electric port. You could see that both devices connect from the electric port so the question occurs of who defined the port, your device or the cable? You will say that the devices define the port, in other words we don't purchase devices depending on port while the port is designed dependent on devices and the cable is just an interface that connects both devices and the port so you could say that a high-level module doesn't depend on the low-level module but both should be dependent on abstraction.
gadgets 【 美 [gæ,dʒɪts] n. 小配件;小工具(gadget的複數)】
翻譯:假想你正坐在辦公桌上,你的桌上有一些零件,例如你的開發機器(液晶顯示器或者筆記本電腦)和手機。液晶顯示器有一個電纜連接到了插板上,並且手機有一根充電線同樣連接到了插板上。你可以看到現在兩個設備都連到了這個插板的埠上,那麼問題出來了,誰定義了這個埠呢,你的設備還是這個電纜線呢?你可能會說,是這些設備定義了這個埠,換句話說,我們不根據埠買這些設備,並且埠的設計是獨立於設備的。並且電纜線僅僅是一個連接設備和埠的介面,所以你可以說一個高層次的模塊不能依賴於低層次的模塊,但是高層次模塊和低層次模塊都應該依賴於抽象模塊。
實際不使用依賴倒置(DIP)的例子
To understand DIP, we use an example that explains how an error log can manage an application. There are two types of log management, the first one is via text file and the other is by using the event viewer. We create a high-level Operation class for error log entry. We create two interfaces, one is IEventViewerLogger and the other is IFileLogger interface. The IEventViewerLogger interface is implemented by the EventViewerLogger class while the IFileLogger interface is implemented by the FileLogger class.
翻譯:為了理解依賴倒置,我們使用了一個例子來解釋:程式中錯誤日誌怎麼管理程式。這裡有兩種類型的日誌系統,第一個是通過文本文件記錄,另外一個是使用事件查看器。我們為錯誤日誌實體創建一個高層次的操作類,然後創建兩個介面,一個是IEventViewerLogger,另外一個是IFileLogger,EventViewerLogger類實現IEventViewerLogger介面,FileLogger類實現IFileLogger介面。
The preceding Figure 1.2 shows that a high-level Operation class depends on the interface. We create an instance of each interface in this class and assign an appropriate object to each instance and use the operation accordingly. This means that a high-level module Operation class depends on the low-level module such as interfaces. Now suppose we want to add a new logger, such as a Database logger. Then we need to add a new interface and that's why the Operation class needs to care for all the interfaces and that's a violation of the Dependency Inversion Principle.
violation 【英 [vaɪə'leɪʃn] 美 [,vaɪə'leʃən] n. 違反;妨礙,侵害;違背;強姦】
翻譯:下圖中,顯示了一個高層次的操作類依賴於介面ILogger,我們在這個高層次的操作類中創建了介面了每個介面的實例【實例介面中定義的成員】,並且根據操作分配合適的對象給每個實例,這樣就意味著高層次的模塊操作類依賴於低層次模塊,例如介面。現在假設,我們想要添加一個新的Logger,例如一個Database Logger,這個時候,我們就需要添加一個新介面,這也是為什麼,這個操作類需要考慮到所有的介面,並且這樣違背了依賴倒置的原則。
實際使用依賴倒置(DIP)的例子【Practical Example with DIP】
DIP states that a high-level module should not depend on a low-level module, both should be dependent on abstraction. To implement this principle we create an ILogger interface that is defined by a high-level module, in other words by an operation class and implemented by low-level modules, both EventViewerLogger and FileLogger classes. So when we add a new Logger, such as a database logger, then we don't need to update the Operation class.
翻譯:依賴倒置原則聲明:一個高級模塊不應該依賴於一個低級模塊,而是高級模塊和低級模塊都應該依賴於一個抽象層。為了實現這個依賴倒置原則,我們創建一個高級模塊定義的ILogger介面,換句話說,這個Ilogger介面被一個操作類定義,被低級模塊(EventViewerLogger和FileLogger類)實現。所以,當我們添加一個新的Logger的時候,例如database Logger,這個時候,我們就不用去更新這個操作類了。
It's a basic introduction to the Dependency Inversion Principle. If you are looking for code for this example then you can visit: Constructor Dependency Injection Pattern Implementation in C#. As I mention in this article that the software design principle is a guideline, in other words DIP doesn't tell us how to solve the preceding problem. If we want to understand how to solve the preceding problem then we need to follow a software design pattern and move onto Inversion of Control.
翻譯:這是一個基本的介紹依賴倒置原則的文章,如果你想這個例子的話,你可以訪問:Constructor Dependency Injection Pattern Implementation in C#.正如我在這篇文章說到的,軟體設計原則是一個指導方針,換句話說,依賴倒置原則並不會告訴我們怎麼去解決前面提到的問題。如果我們想要理解,怎麼去解決前面遇到的問題,我們需要去看下軟體設計模式,順便看看控制反轉。
控制反轉(IOC)模式【Inversion of Control (IoC) Pattern】
DIP is a software design principle that defines a guideline to solve a problem while IoC is a software design pattern that defines how to solve the problem. In other words the IoC is the pattern by which we can practically implement DIP in software development. Let's see an example.
翻譯:依賴倒置原則是軟體設計的原則,它定義了一個指導方針,幫助我們去解決問題。然而IOC是軟體設計模式,IOC幫助我們怎麼去解決問題。換句話說,IOC是模式,通過它我們能夠在軟體開發中實現依賴倒置原則。我們來看一個例子吧。
In the previous error logger example, we define interfaces and implement them in classes. DIP states that a High-level Module should not be depend on a low-level module, that means we define the interface according to a high-level module Operation Class and implemented on a low-level module classes. The IoC is inverting the control of something switching control. In other words an outside module or class is responsible for creating an object of the class instead of directly creating the object of the low-level module class in the high-level module class so we can say that an IoC is an abstraction on which both high-level and low-level modules depend and it inverts the control flow.
invert 【[ɪn'vɜːt] 美 ['ɪnvɝt] vt. 使…轉化;使…顛倒;使…反轉;使…前後倒置 n. 顛倒的事物;倒置物;倒懸者 adj. 轉化的】
翻譯:在前面的錯誤日誌的例子中,我們定義了介面,併在類中實現了介面,依賴倒置原則聲稱:一個高層級的模塊不應該依賴於低層級的模塊,這也就是說,我們根據高層次的操作類來定義這個介面,然後在低層次的類中實現這個介面。IOC是控制反轉的開關。換句話說一個外在的模塊或者一個類是用來創建類的對象的,而不是直接在高層次的模塊類中創建低層次的類的對象。所以我們可以說,IOC就是一個抽象層,不僅僅高級模塊還有低級模塊都依賴於它,IOC使控制發生了反轉。
In short we can say that IoC is used to invert the control flow of the application and an application module interacts with another module via interface and application classes object are created from one class.
翻譯:簡而言之,我們可以說,IOC是用來反轉程式的控制流,並且程式的模塊和其他模塊的交互是通過介面,和其他類中創建的類的對象來實現的。
Dependency Injection (DI)--依賴註入
Dependency Injection (DI) is a type of IoC, it is a pattern where objects are not responsible for creating their own dependencies. Dependency injection is a way to remove hard-coded dependencies among objects, making it easier to replace an object's dependencies, either for testing (using mock objects in unit test) or to change run-time behaviour.
翻譯:依賴註入是控制反轉的一種,它是一種設計模式:對象不負責創建自己的依賴。依賴註入是移除對象之間硬編碼依賴的一種方式。使對象的依賴能夠更容易的被替換,或者說為了更方便測試,或者改變對象運行的時候的行為。
Before understanding Dependency Injection, you should be familiar with the two concepts of Object Oriented Programming, one is tight coupling and another is loose coupling, so let's see each one by one.
理解依賴註入之前,你應該要很熟悉面向對象編程中的兩個概念,一個是緊耦合,另外一個是松耦合,我們來一個一個的看吧:
Tight Coupling: When a class is dependent on a concrete dependency, it is said to be tightly coupled to that class. A tightly coupled object is dependent on another object; that means changing one object in a tightly coupled application often requires changes to a number of other objects. It is not difficult when an application is small but in an enterprise level application, it is too difficult to make the changes.
翻譯:緊耦合:當一個類依賴於一個具體的依賴,也就是說這個類,是緊密耦合的類。一個緊耦合對象依賴於另外一個對象,這意味著改變緊耦合程式中的一個對象,通常需要改變很多其他對象的部分代碼,當應用程式比較小的時候,還不是很難,但是如果應用程式是企業級很大的時候,這樣就變得很難修改了。
Loose Coupling: It means two objects are independent and an object can use another object without being dependent on it. It is a design goal that seeks to reduce the inter-dependencies among components of a system with the goal of reducing the risk that changes in one component will require changes in any other component.
翻譯:松耦合:這意味著兩個對象是相互獨立的,並且一個對象使用另外一個對象而不必依賴於它。松耦合是程式設計的目標,意在尋求減少系統組件之間的內在的相互依賴,並且當我們改變其中一個組件代碼的時候,減少,需要去修改其他組件代碼的風險。
Now in short, Dependency Injection is a pattern that makes objects loosely coupled instead of tightly coupled. Generally we create a concrete class object in the class we require the object and bind it in the dependent class but DI is a pattern where we create a concrete class object outside this high-level module or dependent class.
翻譯:現在簡而言之,就是依賴註入是一個設計模式,它能夠使對象之間成為松耦合,代替原來對象之間的緊耦合。通常,我們在類中創建一個具體的類的對象的時候,我們需要這個對象,捆綁在這個類中,但是依賴註入設計模式下,我們創建一個類的具體對象,在這個高級模塊或者這個類之外,而不必捆綁在這個類中。
There are three types of dependency injections:
- Constructor Dependency Injection
- Setter Dependency Injection
- Interface Dependency Injection
翻譯:這裡有三種類型的依賴註入:
1.構造函數的依賴註入
2.屬性依賴註入
3.介面依賴註入
In this article we will use Constructor Dependency Injection. This is the most commonly used Dependency Injection Pattern in Object Oriented Programming. The Constructor Dependency Injection uses a parameter to inject dependencies so there is normally one parameterized constructor always. So in this constructor dependency, the object has no default constructor and you need to pass specified values at the time of creation to initiate the object. You can say that your design is loosely coupled with the use of constructor dependency injection.
翻譯:在這篇文章中,我將會使用構造函數註入的方式,這是在面向對象編程中,使用的最多的依賴註入方式。構造函數依賴註入,通過使用一個參數來註入依賴,所以通常構造函數都會有一個參數,因此在構造函數依賴中,對象沒有了預設的構造函數,你需要在初始化對象的時候,傳遞一個明確的值。這時候,你可以說,使用構造函數依賴的話,你的設計就是是松耦合的了。
Dependency Injection (DI) Container 【依賴註入容器】
The Dependency Injection Container is a framework to create dependencies and inject them automatically when required. It automatically creates objects based on requests and injects them when required. It helps us split our application into a collection of loosely-coupled, highly-cohesive pieces and then glue them back together in a flexible manner. By DI container, our code will become easier to write, reuse, test and modify. In this article we will use a Niject DI Container.
翻譯:依賴註入容器是一個創建依賴的框架,當需要的時候,容器就會自動的註入依賴。它會基於請求,自動地創建對象,並且當需要依賴的時候,自動註入依賴。它會幫助我們,將程式拆分成松耦合,高內聚的零件,並以靈活的方式,將這些零件重新粘合在一起。通過依賴註入容器,我們的代碼將會變得越來越容易寫,越來越容易測試和修改。這篇文章中我將會使用Niject 依賴註入容器。
好了,到此為止,理論介紹完了,開始實踐吧:
CRUD operations Application Design【增刪查改的應用程式設計】
We create four projects in a solution to implement DIP with generic repository pattern. These are:
我們將會創建四個項目並使用泛型倉儲模式,來實現依賴倒置原則,他們是:
- Ioc.Entities (class library)
- Ioc.Data (class library)
- Ioc.Service (class library)
- Ioc.Web (web application)
首先明確引用關係:Ioc.Data添加Ioc.Entiies引用,Ioc.Service添加Ioc.Entities引用和Ioc.Data引用,最後Ioc.Web添加Ioc.Service和Ioc.Entities引用。
這樣我們就搭建好了基本的框架了。接下來就是開發我們的實體層了。
在這篇文章中,我將會使用EF Code-First方式,來開發引用程式。實體層【Ioc.Entities】中,我們將會創建三個實體,一個是BaseEntity,一個是User實體,另外一個是UserProfile實體,BaseEntity實體類中有一些公共的屬性,另外兩個實體將會繼承BaseEntity實體類。下麵實體層的代碼:
BaseEntity實體類:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ioc.Entities
{
public abstract class BaseEntity
{
/// <summary>
/// Id編號
/// </summary>
public int Id { get; set; }
/// <summary>
/// 添加時間
/// </summary>
public DateTime AddedDate { get; set; }
/// <summary>
/// 修改時間
/// </summary>
public DateTime ModifiedDate { get; set; }
/// <summary>
/// IP地址
/// </summary>
public string IP { get; set; }
}
}
BaseEntity
User實體和UserProfile實體之間是一對一的關係,一個用戶只有一個UserProfile
User實體:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ioc.Entities.User
{
public class User:BaseEntity
{
/// <summary>
/// 用戶名
/// </summary>
public string UserName { get; set; }
/// <summary>
/// 電子郵件
/// </summary>
public string Email { get; set; }
/// <summary>
/// 密碼
/// </summary>
public string Password { get; set; }
/// <summary>
/// 導航屬性--UserProfile
/// </summary>
public virtual UserProfile UserProfile { get; set; }
}
}
User
UserProfile實體:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Ioc.Entities.User
{
public class UserProfile:BaseEntity
{
/// <summary>
/// 姓
/// </summary>
public string FirstName { get; set; }
/// <summary>
/// 名
/// </summary>
public string LastName { get; set; }
/// <summary>
/// 住址
/// </summary>
public string Address { get; set; }
/// <summary>
/// 導航屬性--User
/// </summary>
public virtual User User { get; set; }
}
}
UserProfile
實體層的代碼到此就寫完了,我們看下實體層的結構:
現在開始數據層的開發,因為我們使用EF,所以在Ioc.Data和Ioc.Service以及Ioc.Web項目都引入EF。
先來定義數據上下文介面:
IDbContext介面:
using Ioc.Entities;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ioc.Data
{
public interface IDbContext
{
/// <summary>
/// 泛型返回值類型IDbSet<TEntity>方法Set,並且TEntity要繼承BaseEntity
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <returns></returns>
IDbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity;
/// <summary>
/// 保存
/// </summary>
/// <returns></returns>
int SaveChanges();
}
}
IDbContext
IocDbContext數據上下文類:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace Ioc.Data
{
/// <summary>
/// 數據上下文類,要繼承DbContext類
/// </summary>
public class IocDbContext:DbContext,IDbContext
{
public IocDbContext()
: base("name=DbConnectionstring")
{
}
/// <summary>
/// 重寫DbContext類的OnModelCreating方法
/// </summary>
/// <param name="modelBuilder"></param>
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => !String.IsNullOrEmpty(type.Namespace))
.Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
foreach (var type in typesToRegister)
{
dynamic configurationInstance = Activator.CreateInstance(type);
modelBuilder.Configurations.Add(configurationInstance);
}
base.OnModelCreating(modelBuilder);
}
/// <summary>
/// IocDbContext實現介面IDbContext中的 Set<TEntity>() 方法
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <returns></returns>
public new IDbSet<TEntity> Set<TEntity>() where TEntity : Entities.BaseEntity
{
return base.Set<TEntity>();
//throw new NotImplementedException();//可以看出來,介面的預設實現沒有實現
}
}
}
IocDbContext
Ioc.Data的配置文件中,需要配置資料庫連接字元串:
<connectionStrings>
<add name="DbConnectionstring" connectionString="server=.;database=IocDB;uid=sa;pwd=Password_1" providerName="System.Data.SqlClient"/>
</connectionStrings>
這些配置完了,之後,就是實體的映射類了。還是在Ioc.Data項目中:
UserMap實體類:
using Ioc.Entities.User;
using System;
using System.Collections.Generic;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ioc.Data.Mapping.User
{
/// <summary>
/// 實體映射類,需要繼承EntityTypeConfiguration類
///