In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly explains "how to understand ASP.NET MVC5 website development framework model, data storage, business logic". The content of the article is simple and clear, and it is easy to learn and understand. please follow the editor's train of thought to study and learn "how to understand ASP.NET MVC5 website development framework model, data storage, business logic".
The relationship is as follows
When adopting the three-tier architecture, I have studied the necessity of the BLL layer and found that the business logic can be implemented in controller. There is no need to do a separate project, and more layering will affect performance. Later, I separated the business logic for the following reasons:
The code written into the controller of business logic looks messy, and the code is easy to get confused over time.
Writing logic and repeating code directly in controller will not be more, and the development efficiency is low.
Sub-projects are good for code reuse, and sometimes you can get them directly to other projects and use them with minor modifications.
I think more layering will definitely have an impact on performance, but it won't be very big. Now the update speed of the hardware is much faster than that of the software, it is easy to deal with the business logic, and instantiating a few classes has little impact on performance. Generally speaking, the operation of the website is basically a process of saving the database and fetching the database, and the business logic is still less, but now the website uses more pictures and animations, and the effect is more gorgeous. I think the efficiency bottleneck of the website mainly appears in the server bandwidth, IO performance and access to the database. What can be done in terms of code is to optimize database access. For general projects, in order to run a few percent of the efficiency is far less important than improving development efficiency and easier code management, as long as you can achieve the requirements, running efficiency is not what Daniel needs to do.
For the four projects of IDAL, DAL, IBLL and BLL:
IDAL writes a Base interface, in which several database operation methods are fixed, and all other interfaces are inherited from this interface.
The DAL project does a base class to implement the base interface of the IDAL. All other classes inherit from the base class.
Similarly, a Base interface is written in IBLL to fix several basic operation methods, and other interfaces are also inherited from this base interface.
A base class is also written in IBLL to implement the base interface in IBLL, and other classes inherit from this base class.
Here, the basic pattern of the code is built with actions to the user:
I. Model
Three model classes are written here. Open Ninesk.Models to add three model classes: User, UserGroup, and UserConfig respectively.
1. User model-User class
User model or account model. Why do you say so? look at the following code
Using System;using System.ComponentModel.DataAnnotations;namespace Ninesky.Models {/ user model / create: 2014.02.02 / modify: 2014.02.05 / public class User {[Key] public int UserID {get; set } / user name / [Required (ErrorMessage= "required")] [StringLength (20 minimumLengthreading 4 dint ErrorMessage = "{1} to {0} characters")] [Display (Name= "username")] public string UserName {get; set;} / user group ID / [Required (ErrorMessage= "required")] [Display (Name= "user Group ID")] public int GroupID {get; set } / display name / [Required (ErrorMessage = "required")] [StringLength (20, MinimumLength = 2, ErrorMessage = "{1} to {0} characters")] [Display (Name = "display name")] public string DisplayName {get; set } / password / [Required (ErrorMessage = "required")] [Display (Name = "password")] [DataType (DataType.Password)] public string Password {get; set;} / Required (ErrorMessage = "required")] [Display (Name = "mailbox")] [DataType (DataType.EmailAddress)] public string Email {get; set } / user status / 0 normal, 1 locked, 2 failed email verification, 3 failed administrator / / public int Status {get; set;} / registration time / public DateTime RegistrationTime {get; set;} / last login time / public DateTime LoginTime {get; set } / Last login IP / public DateTime LoginIP {get; set;} public virtual UserGroup Group {get; set;}
This model class contains only user name, password, user group, display name, mailbox and other attributes, purely basic account information, in order to allow users to fill in as little information as possible. If you need other information, you can write a new class to associate with the account, and users can log in when needed and fill it in (such as capital information, personal information, contact information, etc.). Let's not think about that here. The display name here can be used as nickname, real name and so on as needed.
2. User group model-UserGroup class
This class pays attention to GroupType, which is used to classify user groups and is convenient for management. in fact, it has no special significance. My idea is that the general type should be a group of ordinary registered users, and if large websites allow users to upgrade, it should be limited to this type of user group. Privileged groups can put some user groups such as vip, which need to be given by the administrator to distinguish ordinary user groups, but they do not have the right to manage them. The user group of management type needs to be given by the background administrator, and you can manage articles, comments and inquiries.
Using System.ComponentModel.DataAnnotations;namespace Ninesky.Models {/ user group / create: 2014.02.02 / modify: 2014.02.08 / public class UserGroup {[Key] public int GroupID {get; set } / name / / [Required (ErrorMessage= "required")] [StringLength (20, MinimumLength = 2, ErrorMessage= "{1} to {0} words")] [Display (Name= "name")] public string Name {get; set } / user group type / 0 normal type (normal registered user), 1 privilege type (such as VIP), 3 administrative type (type of administrative permission) / [Required (ErrorMessage = "required")] [Display (Name = "user group type")] public int GroupType {get; set } / description / / [Required (ErrorMessage = "required")] [StringLength (50, ErrorMessage = "less than {0} words")] [Display (Name = "description")] public string Description {get; set;}
3. User configuration model class-UserConfig class
This class is some user configuration information (only registration settings are considered for the time being), which are set at the background administrator.
Using System.ComponentModel.DataAnnotations;namespace Ninesky.Models {/ user configuration / create: 2014.02.06 / public class UserConfig {[Key] public int ConfigID {get; set;} / enable registration / [Display (Name = "enable registration")] [Required (ErrorMessage= "required")] public bool Enabled {get; set } / prohibited usernames / usernames are separated by "|" separated / [Display (Name = "prohibited usernames")] public string ProhibitUserName {get; set;} / enable administrator authentication / [Display (Name = "enable administrator authentication")] [Required (ErrorMessage = "required")] public bool EnableAdminVerify {get; set } / enable mail authentication / [Display (Name = "enable mail authentication")] [Required (ErrorMessage = "required")] public bool EnableEmailVerify {get; set;} / default user group Id / [Display (Name = "default user group Id")] [Required (ErrorMessage = "required")] public int DefaultGroupId {get; set;}
II. Data storage layer
The data storage layer is responsible for dealing with the database, resulting in two projects, DAL and IDAL, due to the use of interfaces. IDAL is the interface project and DAL is the implementation project of the interface.
There are some common operations with the convenience of the database, such as add, modify, delete, query and so on. Do not want to write these things in the user class when actually writing the code, the user group class will write it again, and later articles and comments will repeat the code. What are we going to do? get a base class. Later, other classes inherit these public methods from the base class.
1. IDAL project
First open the IDAL project and add the class InterfaceBaseRepository as follows.
Using System;using System.Linq;using System.Linq.Expressions;namespace Ninesky.IDAL {/ Interface base class / create: 2014.02.03 / modify: 2014.02.09 / Type public interface InterfaceBaseRepository {/ add / data entity / added data entity T Add (T entity) / query number of records / conditional expression / number of records int Count (Expression predicate); / update / data entity / successful bool Update (T entity); / delete / data entity / successful bool Delete (T entity) / whether there is a / query expression / Boolean bool Exist (Expression anyLambda); / query data / query expression / entity T Find (Expression whereLambda) / find data list / sort / / query expression / / whether to ascend / / sort expression / IQueryable FindList (Expression whereLamdba, bool isAsc, Expression orderLamdba) / find paged data list / sort / current page / records per page / total records / query expression / / whether ascending / sort expression / IQueryable FindPageList (int pageIndex, int pageSize, out int totalRecord, Expression whereLamdba, bool isAsc, Expression orderLamdba);}}
Here, seven common methods are defined: add, delete, modify, judge existence, return model query, return set query, and return paging set query. These methods basically meet the general needs, and special methods are added when inheriting.
Generics are also used, and passing in entity types when inheriting allows you to inherit these methods directly. If you take a specific look at the InterfaceUserRepository interface, it will be clear.
Using Ninesky.Models;namespace Ninesky.IDAL {/ user interface / create: 2014.02.03 / public interface InterfaceUserRepository:InterfaceBaseRepository {}}
Simply inherit from the InterfaceBaseRepository interface and pass in the entity class User. Let's look in the class view to see if we inherit the interface of the base class.
2. DAL project
DAL project is the implementation of IDAL project interface, the project to create DbContext class, for the DbContext class many people have discussed its efficiency of database access, MSDN said that it is lightweight, the creation does not require much overhead, it is not a thread-safe object, and has the nature of a data container (tracking), so many people think that it should not be static, singularized. However, it is reasonable to implement DbContext only for a single request of the user. Look at the code first, it's very simple.
Using Ninesky.Models;using System.Data.Entity;namespace Ninesky.DAL {/ data context / create: 2014.02.03 / / public class NineskyDbContext:DbContext {public DbSet Users {get; set;} public DbSet UserGroups {get; set;} public DbSet UserConfig {get; set;} public NineskyDbContext (): base ("DefaultConnection") {}}
Let's create a BaseRepository class that inherits from InterfaceBaseRepository and implements the methods of the class's interface.
Using Ninesky.IDAL;using System;using System.Linq;using System.Linq.Expressions;namespace Ninesky.DAL {/ repository base class / create: 2014.02.03 / public class BaseRepository: InterfaceBaseRepository where T: class {protected NineskyDbContext nContext = ContextFactory.GetCurrentContext (); public T Add (T entity) {nContext.Entry (entity). State = System.Data.Entity.EntityState.Added; nContext.SaveChanges (); return entity } public int Count (Expression predicate) {return nContext.Set (). Count (predicate);} public bool Update (T entity) {nContext.Set (). Attach (entity); nContext.Entry (entity). State = System.Data.Entity.EntityState.Modified; return nContext.SaveChanges () > 0;} public bool Delete (T entity) {nContext.Set (). Attach (entity); nContext.Entry (entity). State = System.Data.Entity.EntityState.Deleted Return nContext.SaveChanges () > 0;} public bool Exist (Expression anyLambda) {return nContext.Set (). Any (anyLambda);} public T Find (Expression whereLambda) {T _ entity = nContext.Set (). FirstOrDefault (whereLambda); return _ entity;} public IQueryable FindList (Expression whereLamdba, bool isAsc, Expression orderLamdba) {var _ list = nContext.Set (). Where (whereLamdba); if (isAsc) _ list = _ list.OrderBy (orderLamdba); else _ list = _ list.OrderByDescending (orderLamdba) Return _ list;} public IQueryable FindPageList (int pageIndex, int pageSize, out int totalRecord, Expression whereLamdba, bool isAsc, Expression orderLamdba) {var _ list = nContext.Set (). Where (whereLamdba); totalRecord = _ list.Count (); if (isAsc) _ list = _ list.OrderBy (orderLamdba). Skip ((pageIndex-1) * pageSize). Take (pageSize); else _ list = _ list.OrderByDescending (orderLamdba). Skip ((pageIndex-1) * pageSize) .Take (pageSize); return _ list }}}
The code is full of operations on the database. What is more interesting is the sentence protected NineskyDbContext nContext = ContextFactory.GetCurrentContext ()
ContextFactory is a simple factory class, and GetCurrentContext () is a static function. Use a simple factory to get the current DbContext within the request, that is, the DbContext singleton within the request. Add a factory class ContextFactory first
Using System.Data.Entity;using System.Runtime.Remoting.Messaging;namespace Ninesky.DAL {/ context simple factory / create: 2014.02.05 / public class ContextFactory {/ get the current data context / public static NineskyDbContext GetCurrentContext () {NineskyDbContext _ nContext = CallContext.GetData ("NineskyContext") as NineskyDbContext If (_ nContext = = null) {_ nContext = new NineskyDbContext (); CallContext.SetData ("NineskyContext", _ nContext);} return _ nContext;}
Here, you first get the NineskyContext in CallContext, initialize a NineskyContext if it is empty, and return it directly if it exists. Look at CallContext,MSDN that CallContext provides a unique data slot for each logical execution thread, while in the WEB program, each request happens to be a logical thread, so you can use CallContext to implement a DbContext singleton within a single request.
The specific warehousing code is added below.
Add another UserRepository class to DAL, which inherits from BaseRepository and InterfaceUserRepository. The goal is to inherit from the BaseRepository class and implement the InterfaceUserRepositor interface.
Using Ninesky.IDAL;using Ninesky.Models;using System.Linq;namespace Ninesky.DAL {/ user warehouse / create: 2014.02.03 / class UserRepository: BaseRepository, InterfaceUserRepository {}}
UserRepository directly inherits the methods in the base class, and the methods in the base class can meet most of the needs, so there is no need for UserRepository to add functions. Other Repository classes are similar and do not post code.
Here we are building a Repository factory to return all the Repository classes in the project.
Using Ninesky.IDAL;namespace Ninesky.DAL {/ simple factory? / create: 2014.02.03 / public static class RepositoryFactory {/ user warehousing / public static InterfaceUserRepository UserRepository {get {return new UserRepository ();}}
In the future, when you call it in BLL, you don't have to write InterfaceUserRepository _ iUserRsy = new UserRepository () every time. The advantage of writing InterfaceUserRepository _ iUserRsy = RepositoryFactory.UserRepository directly is that when the class that implements the InterfaceUserRepository interface in the DAL project needs to be modified, we can directly create a new class, and then let the UserRepository property return the new class in the RepositoryFactory class.
3. IBLL project
IBLL is the interface of the business logic layer, and the operation of the business logic layer to the database is basically added, deleted and modified. Also write a base interface to write these three operations, which is similar to the idea of IDAL.
Namespace Ninesky.IBLL {/ Interface base class / create: 2014.02.03 / public interface InterfaceBaseService where T: class {/ add / data entity / added data entity T Add (T entity) / update / data entity / whether the bool Update (T entity) was successful; / delete / data entity / whether the data entity was successful bool Delete (T entity);}}
Add an InterfaceUserService interface that inherits from InterfaceBaseService. Several more methods have been added to the interface as needed. Here, the name of the Find method is unified. if the name of the entity class is Find () or FindByXXX (), the name of the method that returns a set of data is FindList () or FindXXXList, and the name of the page is FindPageList () or FindxxxPageList ().
Using Ninesky.Models;using System.Linq;namespace Ninesky.IBLL {/ user-related interface / create: 2014.02.09 / public interface InterfaceUserService:InterfaceBaseService {/ user name / Boolean value bool Exist (string userName) / find user / user ID / User Find (int userID); / find user / user name / User Find (string userName) / user list / pages / Records per page / Total records / / sort: 0-ID ascending (default), 1ID descending, 2 registration time ascending, 3 registration time descending, 4 login time ascending, 5 login time descending / IQueryable FindPageList (int pageIndex, int pageSize, out int totalRecord,int order);}}
4. BLL project
To implement the InterfaceUserService interface in the BLL project, first add the BaseService
Using Ninesky.IBLL;using Ninesky.IDAL;namespace Ninesky.BLL {/ Service base class / create: 2014.02.03 / / public abstract class BaseService: InterfaceBaseService where T: class {protected InterfaceBaseRepository CurrentRepository {get; set;} public BaseService (InterfaceBaseRepository currentRepository) {CurrentRepository = currentRepository;} public T Add (T entity) {return CurrentRepository.Add (entity);} public bool Update (T entity) {return CurrentRepository.Update (entity) } public bool Delete (T entity) {return CurrentRepository.Delete (entity);}
A parameter to be passed in the constructor of this class is currentRepository, which is passed in when inheriting. Here we still look at the user class.
Using Ninesky.DAL;using Ninesky.IBLL;using Ninesky.Models;using System.Linq;namespace Ninesky.BLL {/ user service class / create: 2014.02.12 / public class UserService:BaseService,InterfaceUserService {public UserService (): base (RepositoryFactory.UserRepository) {} public bool Exist (string userName) {return CurrentRepository.Exist (u = > u.UserName = = userName) } public User Find (int userID) {return CurrentRepository.Find (u = > u.UserID = = userID);} public User Find (string userName) {return CurrentRepository.Find (u = > u.UserName = = userName);} public IQueryable FindPageList (int pageIndex, int pageSize, out int totalRecord, int order) {switch (order) {case 0: return CurrentRepository.FindPageList (pageIndex, pageSize, out totalRecord, u = > true, true, u = > u.UserID) Case 1: return CurrentRepository.FindPageList (pageIndex, pageSize, out totalRecord, u = > true, false, u = > u.UserID); case 2: return CurrentRepository.FindPageList (pageIndex, pageSize, out totalRecord, u = > true, true, u = > u.RegistrationTime); case 3: return CurrentRepository.FindPageList (pageIndex, pageSize, out totalRecord, u = > true, false, u = > u.RegistrationTime); case 4: return CurrentRepository.FindPageList (pageIndex, pageSize, out totalRecord, u = > true, true, u = > u.LoginTime) Case 5: return CurrentRepository.FindPageList (pageIndex, pageSize, out totalRecord, u = > true, false, u = > u.LoginTime); default: return CurrentRepository.FindPageList (pageIndex, pageSize, out totalRecord, u = > true, true, u = > u.UserID);}}
The above FindPageList code is too cumbersome to think of a good way for the time being.
5. Summary
Today, I am still thinking about the implementation of calling between projects. I have written two base interfaces and two base classes, and all other classes inherit from them in a similar way. Next time, you can start working on the interface. In Ninesky.Web projects, you basically deal with data through IBLL,BLL.
=
The sorting method of FindPageList () is really not very general, and the code is modified as follows:
1. Interface InterfaceBaseRepository
Modify the two interface methods as shown in the red box in the figure.
Image
2. BaseRepositor class
Add the OrderBy method as follows:
/ sort / sort / / Type / / original IQueryable / sort attribute name / / whether the sorted IQueryable private IQueryable OrderBy (IQueryable source, string propertyName, bool isAsc) {if (source = = null) throw new ArgumentNullException ("source", "cannot be empty"); if (string.IsNullOrEmpty (propertyName)) return source; var _ parameter = Expression.Parameter (source.ElementType) Var _ property = Expression.Property (_ parameter, propertyName); if (_ property = = null) throw new ArgumentNullException ("propertyName", "property does not exist"); var _ lambda = Expression.Lambda (_ property, _ parameter); var _ methodName = isAsc? "OrderBy": "OrderByDescending"; var _ resultExpression = Expression.Call (typeof (Queryable), _ methodName, new Type [] {source.ElementType, _ property.Type}, source.Expression, Expression.Quote (_ lambda)); return source.Provider.CreateQuery (_ resultExpression);} modify FindList and FindPageList methods, modify the following figure image3, modify UserService's FindPageList method, the modified code is as follows: public IQueryable FindPageList (int pageIndex, int pageSize, out int totalRecord, int order) {bool _ isAsc = true String _ orderName = string.Empty; switch (order) {case 0: _ isAsc = true; _ orderName = "UserID"; break; case 1: _ isAsc = false; _ orderName = "UserID"; break; case 2: _ isAsc = true; _ orderName = "RegistrationTime"; break; case 3: _ isAsc = false; _ orderName = "RegistrationTime"; break Case 4: _ isAsc = true; _ orderName = "LoginTime"; break; case 5: _ isAsc = false; _ orderName = "LoginTime"; break; default: _ isAsc = false; _ orderName = "UserID"; break;} return CurrentRepository.FindPageList (pageIndex, pageSize, out totalRecord, u = > true, _ orderName, _ isAsc) } Thank you for your reading. The above is the content of "how to understand ASP.NET MVC5 website development framework model, data storage and business logic". After the study of this article, I believe you have a deeper understanding of how to understand ASP.NET MVC5 website development framework model, data storage and business logic. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.