zoukankan      html  css  js  c++  java
  • 搭建Wpf框架(4) —— Wpf使用EFCore操作数据库

    前言:1.一般情况下客户端不会直接操作数据库,但是一些比较小型的应用也是可以的。

       2.另外本地一般会用SQLite做本地数据缓存,所以集成一个ORM还是有必要的。

    本框架之前是用Web API获取数据,现在将API切换到EFCore直接连接数据库获取数据。

    之前的架构图:

     

    现在的框架

    基础部分不用动,只用重新对接一些Business层即可。

    之前页面层获取数据的方法为 

     var result = await _dataProvider.GetData<List<SelectOption>>($"/Base_Manage/Base_UserLog/GetLogTypeList");
    

      方法不用变,在di注入的时候,选择不同的dataProvider即可

      //api接口模式
                if (LocalSetting.ApiMode)
                {
                    container.AddNewExtension<Interception>()//add Extension Aop
                        .RegisterSingleton<IDataProvider, ApiDataProvider>(new Interceptor<InterfaceInterceptor>(), new InterceptionBehavior<PolicyInjectionBehavior>());
    
                }
                else//直接访问数据库模式,目前只实现了SqlServer,SQLite
                {
                    container.AddNewExtension<Interception>()//add Extension Aop
                        .RegisterType(typeof(IDataProvider), typeof(EFCoreDataProvider), new Interceptor<InterfaceInterceptor>(), new InterceptionBehavior<PolicyInjectionBehavior>());
    
                    containerRegistry.AddEFCoreServices();
    
                    //初始化数据
                    SeedData.EnsureSeedData();
                }
    

      另外之前的路由解析(/Base_Manage/Base_UserLog/GetLogTypeList)是由服务解析。

    现在为了不改变应用层,那么在EFCoreDataProvider解析参数,并用反射对应的business。

          public async Task<WebResponse<T>> GetData<T>(string url, string json)
            {
                try
                {
                    //url固定是三段,例:Base_Manage/Base_Role/GetOptionList
                    var paras = url.Split(new string[] { @"/" }, StringSplitOptions.RemoveEmptyEntries);
                    //第一段暂时可以
                    //第二段对应不用的business
                    var type = EFCoreDataProviderExtension.AllTypes.FirstOrDefault(p => p.Name == $"I{paras[1]}Business");
                    if (type == null)
                        return WebResponse<T>.Failed((int)ResponseCode.CLIENT_EXCEPTION, "暂不支持");
    
                    //获取接口
                    var business = ContainerLocator.Current.Resolve(type);
                    if (business == null)
                        return WebResponse<T>.Failed((int)ResponseCode.CLIENT_EXCEPTION, "暂不支持");
    
                    //第三段为函数,根据名称获取方法
                    Task task;
                    MethodInfo methodInfo = business.GetType().GetMethod($"{paras[2]}Async");
                    var para = methodInfo.GetParameters()?.FirstOrDefault();
                    if (para != null)
                    {
                        var data = JsonConvert.DeserializeObject(json, para.ParameterType);
                        task = methodInfo.Invoke(business, new Object[] { data }) as Task;
                    }
                    else
                    {
                        task = methodInfo.Invoke(business, new Object[] { }) as Task;
                    }
    
                    await task;
                    //获取执行结果
                    var response = task.GetType().GetProperty("Result").GetValue(task, null);     
                    if (response is AjaxResult) //解析分页数据
                    {                   
                        var pageResult = (response as AjaxResult).ChangeType<AjaxResult<T>>();
                        return WebResponse<T>.Success(pageResult.Data, pageResult.Total);                       
                    }
                    else if (response is T result) //直接解析数据
                    {
                        return WebResponse<T>.Success(result, 1);
                    }
                    else//解析数据(强制转换)
                    {
                        return WebResponse<T>.Success(response.ChangeType<T>(), 1);
                    }
    
                }
                catch (Exception ex)
                {
                    return WebResponse<T>.Failed((int)ResponseCode.CLIENT_EXCEPTION, ex.ToString());
                }
            } 
    

      

      databusiness的实现是将后台的control和business迁移过来的合并的,DataRepository是直接迁移的(从EFCore.Sharding拷贝了一点实现的,大家可以直接看EFCore.Sharding源码,如果是初学者,我这是简单裁剪版,比较容易懂),直接拷贝到任何工程都可以直接使用。

    配置文件App.config:

    <!--<add key="ServerIP" value="http://121.36.12.76:5000"/>--> 
    <add key="UpdateAddress" value="http://121.36.12.76:5000/Update/AutoUpdater.xml"/>
    <add key="ConString" value="Data Source=Admin.db"/>
    <add key="DatabaseType" value="SQLite"/>
    <add key="DeleteMode" value="Logic"/>

    取消ServerIP的注释,那么为API获取数据模式,数据从http://121.36.12.76:5000取

    注释掉ServerIP,那么是使用efcore获取数据,改变ConString和DatabaseType即可。另外,默认数据库删除模式为软删除。

    最后源码地址:艾竹/AIStudio.Wpf.AClient (gitee.com) 

    作者:竹天笑
    互相学习,提高自己。
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    Oracle block 格式
    oracle用户解锁
    如何扩大重做日志(redolog)文件的大小
    Oracle重建临时表空间
    ORA-32004: obsolete and/or deprecated parameter(s) specified
    oracle分布式事务总结(转载)
    spring注解 @Scheduled(cron = "0 0 1 * * *")实现定时的执行任务
    IDEA启动Tomcat报错1099 is already in use
    js中const,var,let区别
    mysql笔记
  • 原文地址:https://www.cnblogs.com/akwkevin/p/14586097.html
Copyright © 2011-2022 走看看