C# EF6+DAL+BLL开发框架

Posted 张喵喵同学

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# EF6+DAL+BLL开发框架相关的知识,希望对你有一定的参考价值。

本文介绍怎样快速创建EF6+DAL+BLL开发框架,开发环境VS2022

 

  • 首先我们新创建一个空白解决方案。

 

 

  • 然后在解决方案下再分别再创建3个类库(.NET Framework)项目,DAL+BLL+Model

 

 

  • 先做项目引用
  • BLL层添加DAL层和Model层

 

  • DAL层添加Model层

 

  • UI层(Web/Winform/WPF)添加BLL层,本文不演示,可以根据自己实际使用的UI来添加引用
  • 然后在Model层添加数据库实体模型,我这里用的是DBFirst,也就是提前创建好数据库

 

  • 实体框架选6.x

 

  • 选择自己的数据库对象,其他默认就好

 

  • 数据库模型有了,接下来在DAL层添加Base文件夹,并新建一个SuperBaseDAL.cs,代码如下

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace DAL

    public class SuperBaseDAL<TEntity> where TEntity : class
    
        protected IDCIMS2023Entities db = new IDCIMS2023Entities();

        public virtual IQueryable<TEntity> FindList<T>(Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, T>> orderLambda, bool isAsc)
        
            var _list = db.Set<TEntity>().Where<TEntity>(whereLambda);
            if (isAsc) _list = _list.OrderBy<TEntity, T>(orderLambda);
            else _list = _list.OrderByDescending<TEntity, T>(orderLambda);
            return _list;
        


        public virtual IQueryable<TEntity> FindPageList<T>(Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, T>> orderLambda, bool isAsc, int page, int pageSize)
        
            var _list = db.Set<TEntity>().Where<TEntity>(whereLambda);
            if (isAsc) _list = _list.OrderBy<TEntity, T>(orderLambda);
            else _list = _list.OrderByDescending<TEntity, T>(orderLambda);
            _list = _list.Skip(pageSize * (page - 1)).Take(pageSize);
            return _list;
        


        //6.0


        /// <summary>
        /// 创建一个原始 SQL 查询,该查询将返回此集中的实体。 默认情况下,上下文会跟踪返回的实体;可通过对返回的 DbSqlQuery<TEntity> 调用 AsNoTracking 来更改此设置。 请注意返回实体的类型始终是此集的类型,而不会是派生的类型。 如果查询的一个或多个表可能包含其他实体类型的数据,则必须编写适当的 SQL 查询以确保只返回适当类型的实体。 与接受 SQL 的任何 API 一样,对任何用户输入进行参数化以便避免 SQL 注入攻击是十分重要的。 您可以在 SQL 查询字符串中包含参数占位符,然后将参数值作为附加参数提供。 您提供的任何参数值都将自动转换为 DbParameter。 context.Blogs.SqlQuery("SELECT * FROM dbo.Posts WHERE Author = @p0", userSuppliedAuthor); 或者,您还可以构造一个 DbParameter 并将它提供给 SqlQuery。 这允许您在 SQL 查询字符串中使用命名参数。 context.Blogs.SqlQuery("SELECT * FROM dbo.Posts WHERE Author = @author", new SqlParameter("@author", userSuppliedAuthor));
        /// </summary>
        /// <param name="sql">sql查询语句</param>
        public virtual IEnumerable<TEntity> SqlQuery(string sql)
        
            return db.Database.SqlQuery<TEntity>(sql);
        


        /// <summary>
        /// 对数据库执行给定的 DDL/DML 命令。 与接受 SQL 的任何 API 一样,对任何用户输入进行参数化以便避免 SQL 注入攻击是十分重要的。 您可以在 SQL 查询字符串中包含参数占位符,然后将参数值作为附加参数提供。 您提供的任何参数值都将自动转换为 DbParameter。 context.Database.ExecuteSqlCommand("UPDATE dbo.Posts SET Rating = 5 WHERE Author = @p0", userSuppliedAuthor); 或者,您还可以构造一个 DbParameter 并将它提供给 SqlQuery。 这允许您在 SQL 查询字符串中使用命名参数。 context.Database.ExecuteSqlCommand("UPDATE dbo.Posts SET Rating = 5 WHERE Author = @author", new SqlParameter("@author", userSuppliedAuthor));
        /// </summary>
        /// <param name="sql">查询语句</param>
        /// <returnT></returnT>
        public virtual bool ExecuteSqlCommand(string sql)
        
            return db.Database.ExecuteSqlCommand(sql) > 0;
        


        /// <summary>
        /// 异步对数据库执行给定的 DDL/DML 命令。 与接受 SQL 的任何 API 一样,对任何用户输入进行参数化以便避免 SQL 注入攻击是十分重要的。 您可以在 SQL 查询字符串中包含参数占位符,然后将参数值作为附加参数提供。 您提供的任何参数值都将自动转换为 DbParameter。 context.Database.ExecuteSqlCommand("UPDATE dbo.Posts SET Rating = 5 WHERE Author = @p0", userSuppliedAuthor); 或者,您还可以构造一个 DbParameter 并将它提供给 SqlQuery。 这允许您在 SQL 查询字符串中使用命名参数。 context.Database.ExecuteSqlCommand("UPDATE dbo.Posts SET Rating = 5 WHERE Author = @author", new SqlParameter("@author", userSuppliedAuthor));
        /// </summary>
        /// <param name="sql">查询语句</param>
        /// <returnT></returnT>
        public virtual async Task<bool> ExcuteSqlCommandAsync(string sql)
        
            return await db.Database.ExecuteSqlCommandAsync(sql) > 0;
        


        /// <summary>
        /// 将给定实体以“已添加”状态添加到集的基础上下文中,这样一来,当调用 SaveChanges 时,会将该实体插入到数据库中。
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returnT></returnT>
        public virtual bool Add(TEntity entity)
        
            db.Set<TEntity>().Add(entity);
            return db.SaveChanges() > 0;
        


        /// <summary>
        /// 异步将给定实体以“已添加”状态添加到集的基础上下文中,这样一来,当调用 SaveChanges 时,会将该实体插入到数据库中。
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returnT></returnT>
        public virtual async Task<bool> AddAsync(TEntity entity)
        
            db.Set<TEntity>().Add(entity);
            return await db.SaveChangesAsync() > 0;
        


        /// <summary>
        /// 将给定实体集合添加到基础化集的上下文中(每个实体都置于“已添加”状态),这样当调用 SaveChanges 时,会将它插入到数据库中。
        /// </summary>
        /// <param name="entities">合集</param>
        /// <returnT></returnT>
        public virtual bool AddRange(IEnumerable<TEntity> entities)
        
            db.Set<TEntity>().AddRange(entities);
            return db.SaveChanges() > 0;
        


        /// <summary>
        /// 异步将给定实体集合添加到基础化集的上下文中(每个实体都置于“已添加”状态),这样当调用 SaveChanges 时,会将它插入到数据库中。
        /// </summary>
        /// <param name="entities">合集</param>
        /// <returnT></returnT>
        public virtual async Task<bool> AddRangeAsync(IEnumerable<TEntity> entities)
        
            db.Set<TEntity>().AddRange(entities);
            return await db.SaveChangesAsync() > 0;
        


        /// <summary>
        /// 将给定实体标记为“已删除”,这样一来,当调用 SaveChanges 时,将从数据库中删除该实体。 请注意,在调用此方法之前,该实体必须以另一种状态存在于该上下文中。
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returnT></returnT>
        public virtual bool Remove(TEntity entity)
        
            db.Set<TEntity>().Remove(entity);
            return db.SaveChanges() > 0;
        


        /// <summary>
        /// 异步将给定实体标记为“已删除”,这样一来,当调用 SaveChanges 时,将从数据库中删除该实体。 请注意,在调用此方法之前,该实体必须以另一种状态存在于该上下文中。
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returnT></returnT>
        public virtual async Task<bool> RemoveAsync(TEntity entity)
        
            db.Set<TEntity>().Remove(entity);
            return await db.SaveChangesAsync() > 0;
        


        /// <summary>
        /// 从基础化集的上下文中删除给定实体集合(每个实体都置于“已删除”状态),这样当调用 SaveChanges 时,会从数据库中删除它。
        /// </summary>
        /// <param name="entities">合集</param>
        /// <returnT></returnT>
        public virtual bool RemoveRange(IEnumerable<TEntity> entities)
        
            db.Set<TEntity>().RemoveRange(entities);
            return db.SaveChanges() > 0;
        


        /// <summary>
        /// 异步从基础化集的上下文中删除给定实体集合(每个实体都置于“已删除”状态),这样当调用 SaveChanges 时,会从数据库中删除它。
        /// </summary>
        /// <param name="entities">合集</param>
        /// <returnT></returnT>
        public virtual async Task<bool> RemoveRangeAsync(IEnumerable<TEntity> entities)
        
            db.Set<TEntity>().RemoveRange(entities);
            return await db.SaveChangesAsync() > 0;
        


        /// <summary>
        /// 重载。 调用 SaveChanges 时,按键添加或更新实体。 等效于数据库术语中的“upsert”操作。 此方法在使用迁移设置数据的种子时很有用。 (由 DbSetMigrationsExtensions 定义。)
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returnT></returnT>
        public virtual bool AddOrUpdate(TEntity entity)
        
            db.Set<TEntity>().AddOrUpdate(entity);
            return db.SaveChanges() > 0;
        


        /// <summary>
        /// 重载。 异步调用 SaveChanges 时,按键添加或更新实体。 等效于数据库术语中的“upsert”操作。 此方法在使用迁移设置数据的种子时很有用。 (由 DbSetMigrationsExtensions 定义。)
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returnT></returnT>
        public virtual async Task<bool> AddOrUpdateAsync(TEntity entity)
        
            db.Set<TEntity>().AddOrUpdate(entity);
            return await db.SaveChangesAsync() > 0;
        


        /// <summary>
        /// 重载。 确定序列的任何元素是否满足条件。 (由 QueryableExtensions 定义。)
        /// </summary>
        /// <param name="anyLambda"></param>
        /// <returnT></returnT>
        public virtual bool Exists(Expression<Func<TEntity, bool>> anyLambda)
        
            return db.Set<TEntity>().Any(anyLambda);
        


        /// <summary>
        /// 重载。 异步确定序列的任何元素是否满足条件。 (由 QueryableExtensions 定义。)
        /// </summary>
        /// <param name="anyLambda"></param>
        /// <returnT></returnT>
        public virtual async Task<bool> ExistsAsync(Expression<Func<TEntity, Boolean>> anyLambda)
        
            return await db.Set<TEntity>().AnyAsync(anyLambda);
        


        /// <summary>
        /// 查找带给定主键值的实体。 如果上下文中存在带给定主键值的实体,则立即返回该实体,而不会向存储区发送请求。 否则,会向存储区发送查找带给定主键值的实体的请求,如果找到该实体,则将其附加到上下文并返回。 如果未在上下文或存储区中找到实体,则返回 null。
        /// </summary>
        /// <param name="key"></param>
        /// <returnT></returnT>
        public virtual TEntity Find(object key)
        
            return db.Set<TEntity>().Find(key);
        


        /// <summary>
        /// 异步查找带给定主键值的实体。 如果上下文中存在带给定主键值的实体,则立即返回该实体,而不会向存储区发送请求。 否则,会向存储区发送查找带给定主键值的实体的请求,如果找到该实体,则将其附加到上下文并返回。 如果未在上下文或存储区中找到实体,则返回 null。
        /// </summary>
        /// <param name="key"></param>
        /// <returnT></returnT>
        public virtual async Task<TEntity> FindAsync(object key)
        
            return await db.Set<TEntity>().FindAsync(key);
        


        /// <summary>
        /// 重载。 异步返回序列的第一个元素。
        /// </summary>
        /// <param name="whereLambda">查询表达式</param>
        /// <returnT></returnT>
        public virtual TEntity Find(Expression<Func<TEntity, bool>> whereLambda)
        
            return db.Set<TEntity>().FirstOrDefault<TEntity>(whereLambda);
        


        /// <summary>
        /// 重载。 异步返回序列的第一个元素。
        /// </summary>
        /// <param name="whereLambda">查询表达式</param>
        /// <returnT></returnT>
        public virtual async Task<TEntity> FindAsync(Expression<Func<TEntity, bool>> whereLambda)
        
            return await db.Set<TEntity>().FirstOrDefaultAsync<TEntity>(whereLambda);
        


        /// <summary>
        /// 重载。 异步枚举查询结果并对每个元素执行指定的操作。 (由 QueryableExtensions 定义。)
        /// </summary>
        /// <param name="obj"></param>
        /// <returnT></returnT>
        public virtual async Task ForeachAsync(Action<TEntity> obj)
        
            await db.Set<TEntity>().ForEachAsync(obj);
        


        /// <summary>
        /// 重载。 返回序列中的元素数。 (由 QueryableExtensions 定义。)
        /// </summary>
        /// <returnT></returnT>
        public virtual int Count()
        
            return db.Set<TEntity>().Count();
        


        /// <summary>
        /// 重载。 异步返回序列中的元素数。 (由 QueryableExtensions 定义。)
        /// </summary>
        /// <returnT></returnT>
        public virtual async Task<int> CountAsync()
        
            return await db.Set<TEntity>().CountAsync();
        


        /// <summary>
        /// 重载。 返回满足条件的序列中的元素数。
        /// </summary>
        /// <param name="predicate">查询表达式</param>
        /// <returnT></returnT>
        public virtual int Count(Expression<Func<TEntity, bool>> predicate)
        
            return db.Set<TEntity>().Count(predicate);
        


        /// <summary>
        /// 重载。 返回满足条件的序列中的元素数。
        /// </summary>
        /// <param name="predicate">查询表达式</param>
        /// <returnT></returnT>
        public virtual async Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate)
        
            return await db.Set<TEntity>().CountAsync(predicate);
        
    

 

 

  • 接着对着类名右键-快速操作和重构-提取接口

 

  • 全选确定

 

  • 提取接口后,基类SuperBaseDAL自动继承了接口

 

  • 来到这里,我发现DAL层并没有安装EntityFramework,可以通过NuGet安装

  • 通过NuGet,我们发现model层已经安装,但DAL层没有,所有这里我们勾选DAL层点安装就可以了

 

  • 接下来可以在DAL层创建数据库实体的数据处理类了

 

  • 继承SuperBaseDAL<UserInfo>

 

  • 生成重写

 

 

  • 选择要重写的成员,我这里选全部

 

 

 

 

  • UserInfoDAL.cs 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Model;

namespace DAL

    internal class UserInfoDAL : SuperBaseDAL<UserInfo>
    
        public override bool Add(UserInfo entity)
        
            return base.Add(entity);
        

        public override Task<bool> AddAsync(UserInfo entity)
        
            return base.AddAsync(entity);
        

        public override bool AddOrUpdate(UserInfo entity)
        
            return base.AddOrUpdate(entity);
        

        public override Task<bool> AddOrUpdateAsync(UserInfo entity)
        
            return base.AddOrUpdateAsync(entity);
        

        public override bool AddRange(IEnumerable<UserInfo> entities)
        
            return base.AddRange(entities);
        

        public override Task<bool> AddRangeAsync(IEnumerable<UserInfo> entities)
        
            return base.AddRangeAsync(entities);
        

        public override int Count()
        
            return base.Count();
        

        public override int Count(Expression<Func<UserInfo, bool>> predicate)
        
            return base.Count(predicate);
        

        public override Task<int> CountAsync()
        
            return base.CountAsync();
        

        public override Task<int> CountAsync(Expression<Func<UserInfo, bool>> predicate)
        
            return base.CountAsync(predicate);
        

        public override bool Equals(object obj)
        
            return base.Equals(obj);
        

        public override Task<bool> ExcuteSqlCommandAsync(string sql)
        
            return base.ExcuteSqlCommandAsync(sql);
        

        public override bool ExecuteSqlCommand(string sql)
        
            return base.ExecuteSqlCommand(sql);
        

        public override bool Exists(Expression<Func<UserInfo, bool>> anyLambda)
        
            return base.Exists(anyLambda);
        

        public override Task<bool> ExistsAsync(Expression<Func<UserInfo, bool>> anyLambda)
        
            return base.ExistsAsync(anyLambda);
        

        public override UserInfo Find(object key)
        
            return base.Find(key);
        

        public override UserInfo Find(Expression<Func<UserInfo, bool>> whereLambda)
        
            return base.Find(whereLambda);
        

        public override Task<UserInfo> FindAsync(object key)
        
            return base.FindAsync(key);
        

        public override Task<UserInfo> FindAsync(Expression<Func<UserInfo, bool>> whereLambda)
        
            return base.FindAsync(whereLambda);
        

        public override IQueryable<UserInfo> FindList<T>(Expression<Func<UserInfo, bool>> whereLambda, Expression<Func<UserInfo, T>> orderLambda, bool isAsc)
        
            return base.FindList(whereLambda, orderLambda, isAsc);
        

        public override IQueryable<UserInfo> FindPageList<T>(Expression<Func<UserInfo, bool>> whereLambda, Expression<Func<UserInfo, T>> orderLambda, bool isAsc, int page, int pageSize)
        
            return base.FindPageList(whereLambda, orderLambda, isAsc, page, pageSize);
        

        public override Task ForeachAsync(Action<UserInfo> obj)
        
            return base.ForeachAsync(obj);
        

        public override int GetHashCode()
        
            return base.GetHashCode();
        

        public override bool Remove(UserInfo entity)
        
            return base.Remove(entity);
        

        public override Task<bool> RemoveAsync(UserInfo entity)
        
            return base.RemoveAsync(entity);
        

        public override bool RemoveRange(IEnumerable<UserInfo> entities)
        
            return base.RemoveRange(entities);
        

        public override Task<bool> RemoveRangeAsync(IEnumerable<UserInfo> entities)
        
            return base.RemoveRangeAsync(entities);
        

        public override IEnumerable<UserInfo> SqlQuery(string sql)
        
            return base.SqlQuery(sql);
        

        public override string ToString()
        
            return base.ToString();
        
    

 

 

  • 接下来可以去BLL项目下,创建一个对UserInfo的业务逻辑处理类UserInfoBLL.cs,然后继承ISuperBaseDAL并实现接口

  • UserInfoBLL.cs

using DAL;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace BLL

    public class UserInfoBLL : ISuperBaseDAL<UserInfo>
    
        public bool Add(UserInfo entity)
        
            throw new NotImplementedException();
        

        public Task<bool> AddAsync(UserInfo entity)
        
            throw new NotImplementedException();
        

        public bool AddOrUpdate(UserInfo entity)
        
            throw new NotImplementedException();
        

        public Task<bool> AddOrUpdateAsync(UserInfo entity)
        
            throw new NotImplementedException();
        

        public bool AddRange(IEnumerable<UserInfo> entities)
        
            throw new NotImplementedException();
        

        public Task<bool> AddRangeAsync(IEnumerable<UserInfo> entities)
        
            throw new NotImplementedException();
        

        public int Count()
        
            throw new NotImplementedException();
        

        public int Count(Expression<Func<UserInfo, bool>> predicate)
        
            throw new NotImplementedException();
        

        public Task<int> CountAsync()
        
            throw new NotImplementedException();
        

        public Task<int> CountAsync(Expression<Func<UserInfo, bool>> predicate)
        
            throw new NotImplementedException();
        

        public Task<bool> ExcuteSqlCommandAsync(string sql)
        
            throw new NotImplementedException();
        

        public bool ExecuteSqlCommand(string sql)
        
            throw new NotImplementedException();
        

        public bool Exists(Expression<Func<UserInfo, bool>> anyLambda)
        
            throw new NotImplementedException();
        

        public Task<bool> ExistsAsync(Expression<Func<UserInfo, bool>> anyLambda)
        
            throw new NotImplementedException();
        

        public UserInfo Find(Expression<Func<UserInfo, bool>> whereLambda)
        
            throw new NotImplementedException();
        

        public UserInfo Find(object key)
        
            throw new NotImplementedException();
        

        public Task<UserInfo> FindAsync(Expression<Func<UserInfo, bool>> whereLambda)
        
            throw new NotImplementedException();
        

        public Task<UserInfo> FindAsync(object key)
        
            throw new NotImplementedException();
        

        public IQueryable<UserInfo> FindList<T>(Expression<Func<UserInfo, bool>> whereLambda, Expression<Func<UserInfo, T>> orderLambda, bool isAsc)
        
            throw new NotImplementedException();
        

        public IQueryable<UserInfo> FindPageList<T>(Expression<Func<UserInfo, bool>> whereLambda, Expression<Func<UserInfo, T>> orderLambda, bool isAsc, int page, int pageSize)
        
            throw new NotImplementedException();
        

        public Task ForeachAsync(Action<UserInfo> obj)
        
            throw new NotImplementedException();
        

        public bool Remove(UserInfo entity)
        
            throw new NotImplementedException();
        

        public Task<bool> RemoveAsync(UserInfo entity)
        
            throw new NotImplementedException();
        

        public bool RemoveRange(IEnumerable<UserInfo> entities)
        
            throw new NotImplementedException();
        

        public Task<bool> RemoveRangeAsync(IEnumerable<UserInfo> entities)
        
            throw new NotImplementedException();
        

        public IEnumerable<UserInfo> SqlQuery(string sql)
        
            throw new NotImplementedException();
        
    

 

我们只要根据实际业务逻辑,去修改UserInfoBLL.cs就可以直接用了~~

本文结束,感谢收看~ 

以上是关于C# EF6+DAL+BLL开发框架的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET MVC5+EF6搭建三层实例

具有存储库模式的实体框架 DAL、BLL

C# |如何制作用于将数据从 DAL 传递到 BLL 的类实例(对象)

在我的 API 中使用 BLL 函数而不参考 DAL

在ASP.NET中,三层架构,Web ,BLL,DAL,Models这四个的引用关系是?

BLL,DAL,BO,插入数据