MVVM+三层架构+SqlSugar(code First)

本篇文章主要分享本人对MVVM,三层架构与ORM框架的一些心得,如果各路大神有其他看法可以在评论区评论,欢迎各位提出指导意见。废话不多说直接上图上代码。

这个软件是以学生信息管理系统为例子,UI 层提供对学生信息的增加,删除,修改,查询功能,对应到底层对数据库实现增删改查的操作.下面我就以三层架构的思维从上往下一一描述。

1.UI 层

这里采用了MVVM 的设计架构,目的是让视图代码和数据模型降低耦合,实现属性,方法的绑定。在控件上我稍微使用了控件模板和样式。

(1)View 代码:


    
             
        
    
    
        
            
            
        
        
            
                
                
                
                
            
            
                
                    
                
            
        
        
            
                
                
            
            
                
                    
                        
                        
                        
                        
                    
                    
                        
                    
                        
                    
                        
                    
                        
                
            
            
                
                    
                        
                        
                        
                        
                    
                    


PS:在界面底下构造需要把Viewmodel 的数据绑定到前端中,可以组合引用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using MVVMTest.ViewModel;
using MVVMTest.View;


namespace MVVMTest.View
{
    /// 
    /// MainWindow.xaml 的交互逻辑
    /// 
    public partial class MainWindow : Window
    {     
        public MainWindow()
        {
            InitializeComponent();
            DataContext = MainViewModel.Instance;
        }

    }

}

  

(2)ViewModel 代码(这里跟事件的绑定我使用了Prism 框架,因为不想自己造轮子,其他的框架也是可以的,这块业务我使用了单例去设计)

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using MVVMTest.Model;
using Prism.Commands;

namespace MVVMTest.ViewModel
{
    public class MainViewModel
    {
        static MainViewModel()
        {
        }
        private MainViewModel()
        {
            IniViewModel();
            BusinessLogic.BusinessLogic.Instance.SetRequest(studentModel.GetType());
        }
        public static MainViewModel Instance { get; } = new MainViewModel(); //这里使用单例去做业务处理
        
        //控件命令列表
        // Prism 框架下的事件绑定,可带参和不带参
        private DelegateCommand _buttonQueryCommand;
        public DelegateCommand buttonQueryCommand =>
            _buttonQueryCommand ?? (_buttonQueryCommand = new DelegateCommand(ViewQuery));

        private DelegateCommand _buttonInsertCommand;
        public DelegateCommand buttonInsertCommand =>
           _buttonInsertCommand ?? (_buttonInsertCommand = new DelegateCommand(ViewInsert));

        private DelegateCommand _buttonUpdataCommand;
        public DelegateCommand buttonUpdataCommand =>
           _buttonUpdataCommand ?? (_buttonUpdataCommand = new DelegateCommand(ViewUpdata));

        private DelegateCommand _buttonDeleteCommand;
        public DelegateCommand buttonDeleteCommand =>
           _buttonDeleteCommand ?? (_buttonDeleteCommand = new DelegateCommand(ViewDelete));

        private DelegateCommand _selectItemChangedCommand;
        public DelegateCommand selectItemChangedCommand =>
           _selectItemChangedCommand ?? (_selectItemChangedCommand = new DelegateCommand(GetModelObject));

        public StudentModel studentModel { get; set; }

        private StudentModel selectStudentModel = new StudentModel();

        private void IniViewModel()
        {
            studentModel = new StudentModel();
        }     
        private void ViewQuery()
        {
            studentModel.StudentList = BusinessLogic.BusinessLogic.Instance.QueryData();
        }
        private void ViewInsert()
        {           
            BusinessLogic.BusinessLogic.Instance.InsertData(studentModel);           
        }
        private void ViewUpdata()
        {
            selectStudentModel.Name = studentModel.Name;
            selectStudentModel.Year = studentModel.Year;
            selectStudentModel.Address = studentModel.Address;
            selectStudentModel.PhoneNumber = studentModel.PhoneNumber;
            BusinessLogic.BusinessLogic.Instance.UpdataData(selectStudentModel);
        }
        private void ViewDelete()
        {
            BusinessLogic.BusinessLogic.Instance.DeleteData(selectStudentModel);
        }
        private void GetModelObject(object obj)
        {
           if(obj!=null)
            {
                selectStudentModel = obj as StudentModel;
            }
        }        

    }
}

Model 层(Model 层主要用来创建数据模型 和 对数据库的映射,我这里使用了SqlSuger  Code First 去实现数据库映射,同是界面对数据模型双向绑定 INotifyPropertyChanged 这个接口主要实现通知客户端数据刷新,System自带接口)

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SqlSugar;


namespace MVVMTest.Model
{
    [SugarTable("StudentData")]  //映射表名
    public class StudentModel : INotifyPropertyChanged
    {

        private string _Name { get; set; }
        [SugarColumn(IsNullable =true)]
        public string Name
        {
            get { return _Name; }
            set
            {
                _Name = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name"));
            }
        }

        private int _Id { get; set; }
        [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] //主键
        public int Id { get { return _Id; } set { _Id = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Id")); } }

        
        private string _Year { get; set; }
        [SugarColumn(IsNullable = true)]
        public string Year { get { return _Year; } set { _Year = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Year")); } }

        private string _Address { get; set; }
        [SugarColumn(IsNullable = true)]
        public string Address { get { return _Address; } set { _Address = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Address")); } }

        private string _PhoneNumber { get; set; }
        [SugarColumn(IsNullable = true)]
        public string PhoneNumber { get { return _PhoneNumber; } set { _PhoneNumber = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("PhoneNumber")); } }

        [SugarColumn(IsIgnore = true)]
        public List StudentList { get { return studentData; } set { studentData = value;PropertyChanged?.Invoke(this,new PropertyChangedEventArgs("StudentList")); } }
      
        private List studentData = new List() {  };

       
        public event PropertyChangedEventHandler PropertyChanged;

    }
}

2.业务逻辑层(这里我也用了单例,并且保证线程安全)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using MVVMTest.DataAccess.DataBase;
using MVVMTest.Common;
using MVVMTest.Model;
using System.Data;
using System.Collections;
using System.Reflection;

namespace MVVMTest.BusinessLogic
{
    class BusinessLogic
    {
        private BusinessLogic()
        {
           
        }
        private static readonly object obj=new object();
        private volatile static  BusinessLogic instance = null;
        SqlSugerHelper sqlSugerHelper = new SqlSugerHelper();
        public static  BusinessLogic Instance
        {
            get
            {
              if(instance==null)
                {
                    lock(obj)
                    {
                        if(instance == null)
                        instance = new BusinessLogic();
                    }
                        
                }
                return instance;
            }
            
        }
       public void SetRequest(Type dataModel)
        {                      
            sqlSugerHelper.IniDB(GlobelEnum.DatabaseType.SqlServer, dataModel);
        }
        public void InsertData(StudentModel studentModel)
        {
            sqlSugerHelper.Insert(studentModel);
        }
        public List QueryData()
        {
            List dataTable = new List();
            dataTable = sqlSugerHelper.Query();
            return dataTable;
        }
        public void DeleteData(StudentModel studentModel)
        {
            sqlSugerHelper.Delete(studentModel);
        }
        public void UpdataData(StudentModel studentModel)
        {
            sqlSugerHelper.Updata(studentModel);
        }
        private DataTable ListToDt(IEnumerable collection)
        {
            var props = typeof(T).GetProperties();
            var dt = new DataTable();
            dt.Columns.AddRange(props.Select(p => new
            DataColumn(p.Name, p.PropertyType)).ToArray());
            if (collection.Count() > 0)
            {
                for (int i = 0; i < collection.Count(); i++)
                {
                    ArrayList tempList = new ArrayList();
                    foreach (PropertyInfo pi in props)
                    {
                        object obj = pi.GetValue(collection.ElementAt(i), null);
                        tempList.Add(obj);
                    }
                    object[] array = tempList.ToArray();
                    dt.LoadDataRow(array, true);
                }
            }
            return dt;
        }

    }
}


 

3.数据访问层(这里针对不同的数据库我使用了工厂模式去实现,由用户使用的时候再去选择实例哪一个数据库,这里的代码可能处理的不太好,欢迎大家发表不同意见)

(1)数据库基类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using SqlSugar;

namespace MVVMTest.DataAccess.DataBase
{
    public abstract class SqlBase
    {
        public abstract SqlSugarClient IniDb(Type DataModel, string DataBaseName, string ServerName) ;       
      
    }
}


(2)数据库子类(SqlSever)(这里设计SqlSuger Code First 的代码)

using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MVVMTest.DataAccess.DataBase
{
    public class SqlSever : SqlBase
    {
     
        public override SqlSugarClient IniDb(Type DataModel, string DataBaseName, string ServerName ) 
        {
            SqlSugarClient db = new SqlSugarClient(new ConnectionConfig()
            {
                ConnectionString =string.Format("server={0};database={1};uid=数据库账户;pwd=密码, ServerName, DataBaseName), 
                DbType = SqlSugar.DbType.SqlServer,//设置数据库类型
                IsAutoCloseConnection = true,//自动释放数据务,如果存在事务,在事务结束后释放
                InitKeyType = InitKeyType.Attribute //从实体特性中读取主键自增列信息
            });

            db.Aop.OnLogExecuting = (sql, pars) =>
            {
                Console.WriteLine(sql + "\r\n" +
                db.Utilities.SerializeObject(pars.ToString()));  //打印数据库日志
                Console.WriteLine();
            };
            //创建数据库 如果该库不存在,则进行创建。(这里创建的是名字为 Student 数据库)
            db.DbMaintenance.CreateDatabase();
            //初始化数据表,如果没有则创建
            db.CodeFirst.InitTables(DataModel);           
            return db;
        }
    }
}

(3)数据库子类(Sqlite)

using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MVVMTest.DataAccess.DataBase
{
    public class Sqlite : SqlBase
    {
       
        public override SqlSugarClient IniDb(Type DataModel, string DataBaseName, string ServerName)
        {
            SqlSugarClient db = new SqlSugarClient(new ConnectionConfig()
            {
                ConnectionString = string.Format("server={0};database={1};uid=数据库账户;pwd=密码", ServerName, DataBaseName),
                DbType = SqlSugar.DbType.Sqlite,//设置数据库类型
                IsAutoCloseConnection = true,//自动释放数据务,如果存在事务,在事务结束后释放
                InitKeyType = InitKeyType.Attribute //从实体特性中读取主键自增列信息
            });

            db.Aop.OnLogExecuting = (sql, pars) =>
            {
                Console.WriteLine(sql + "\r\n" +
                db.Utilities.SerializeObject(pars.ToString()));
                Console.WriteLine();
            };
            //创建数据库 如果该库不存在,则进行创建。(这里创建的是名字为 Student 数据库)
            db.DbMaintenance.CreateDatabase();
            //初始化数据表,如果没有则创建
            db.CodeFirst.InitTables(DataModel);
            return db;
        }
     
    }
}


(4) 数据库工厂

using MVVMTest.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace MVVMTest.DataAccess.DataBase
{
    public class DataBaseFactory
    {
        private DataBaseFactory()
        {

        }
        static DataBaseFactory() { }
        public  static DataBaseFactory Instance { get; } = new DataBaseFactory();

        public SqlBase Create(GlobelEnum.DatabaseType databaseType)
        {
            SqlBase dataBaseFactory = null; 
            switch(databaseType)
            {
                case GlobelEnum.DatabaseType.MySql:
                    break;
                case GlobelEnum.DatabaseType.SqlServer:
                    dataBaseFactory = new SqlSever();
                    break;
            }
            return dataBaseFactory;
        }
    }
}


(5)数据库访问接口

using MVVMTest.Common;
using MVVMTest.Model;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MVVMTest.Model;
using System.Data;

namespace MVVMTest.DataAccess.DataBase
{
    public class SqlSugerHelper
    {

        SqlBase sqlBase;
        SqlSugarClient sqlSugarClient;
        public void IniDB(GlobelEnum.DatabaseType databaseType, Type dataModel)
        {

            sqlBase = DataBaseFactory.Instance.Create(databaseType);
            sqlSugarClient = sqlBase.IniDb(dataModel, "Student", "服务器名称");
        }
        public void Insert(StudentModel studentModel)
        {
           
                sqlSugarClient.Insertable(studentModel).ExecuteCommand();
                //var a = sqlSugarClient.Ado.SqlQuery("select * from StudentData"); // 数据库语句
        }
        public List Query()
        {
            List studentModels = new List();
            studentModels=sqlSugarClient.Queryable().ToList();
            sqlSugarClient.Close();
            return studentModels;
        }

        public void Delete(StudentModel studentModel)
        {           
            sqlSugarClient.Deleteable(studentModel).ExecuteCommand();
        }
        public void Updata(StudentModel studentModel)
        {
            sqlSugarClient.Updateable(studentModel).ExecuteCommand();
        }

    }
}

公共类

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

namespace MVVMTest.Common
{
   public static class GlobelEnum
    {
      public  enum SqlCommand
        {
            Invalid=-1,
            IniDB=0,
            Query=1,
            Insert=2,
            Updata=3,
            Delete=4,
        }

        public enum DatabaseType
        {
            Invalid=0,
            Sqlite=1,
            SqlServer=2,
            MySql=3,
        }

        public enum ORMType
        {
            Invalid = 0,
            CodeFirst=1,
            DBFirst=2,
            ModelFirst=3,
        }

    }
}


 

公共类中有一些是不需要的枚举,可以不用完全借鉴

欢迎各位大神指导评论
 

你可能感兴趣的:(架构,c#,wpf,sqlserver)