1:IBaseDAL
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Linq.Expressions; 5 using System.Text; 6 using System.Threading.Tasks; 7 8 namespace C01.ZRF.IDAL 9 { 10 public interface IBaseDAL<T> where T : class 11 { 12 13 int SaveChanges(); 14 15 void Add(T model); 16 17 void Delete(T model); 18 19 void DeleteBy(System.Linq.Expressions.Expression<Func<T, bool>> delWhere); 20 21 void Modify(T model, params string[] propertyNames); 22 23 IQueryable<T> Where(Expression<Func<T, bool>> whereLambda); 24 25 IQueryable<T> WhereOrder<TKey>(Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> keySelector, bool isAsc = true); 26 27 IQueryable<T> WhereInclude(Expression<Func<T, bool>> whereLambda, params string[] includePropertyNames); 28 29 IQueryable<T> WhereInclude<TKey>(Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> keySelector, bool isAsc = true, params string[] includePropertyNames); 30 31 IEnumerable<T> WherePaged<TKey>(int PageIndex, int PageSize, out int totalCount, Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> keySelector, bool isAsc = true, params string[] includePropertyNames); 32 33 IQueryable<T> QueryBySql(string sql, params System.Data.SqlClient.SqlParameter[] ps); 34 } 35 }
View Code
T4模板生成的接口
<#@ template language="C#" debug="false" hostspecific="true"#> <#@ include file="EF.Utility.CS.ttinclude"#> <#@ output extension=".cs"#> <# CodeGenerationTools code = new CodeGenerationTools(this); MetadataLoader loader = new MetadataLoader(this); CodeRegion region = new CodeRegion(this, 1); MetadataTools ef = new MetadataTools(this); string inputFile1 = @"E:\Temp\test01\3LaySolution\C10.ZRF.Model\Model1.edmx"; EdmItemCollection ItemCollection1 = loader.CreateEdmItemCollection(inputFile1); string namespaceName = code.VsNamespaceSuggestion(); EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this); #> using System; using System.Collections.Generic; using System.Linq; using System.Text; using C10.ZRF.Model; namespace C01.ZRF.IDAL { <# foreach (EntityType entity in ItemCollection1.GetItems<EntityType>().OrderBy(e => e.Name)) { #> public partial interface I<#=entity.Name#>_DAL : IBaseDAL<<#=entity.Name#>>{ } <#}#> }
View Code
生成后的效果如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using C10.ZRF.Model; namespace C01.ZRF.IDAL { public partial interface IBuyCar_DAL : IBaseDAL<BuyCar>{ } public partial interface IMenu_DAL : IBaseDAL<Menu>{ } public partial interface IProduct_DAL : IBaseDAL<Product>{ } public partial interface IRole_DAL : IBaseDAL<Role>{ } public partial interface IroleMenu_DAL : IBaseDAL<roleMenu>{ } public partial interface IuerRole_DAL : IBaseDAL<uerRole>{ } public partial interface IUser_DAL : IBaseDAL<User>{ } }
View Code
2:DAL
1 using System; 2 using System.Collections.Generic; 3 using System.Data.Entity.Infrastructure; 4 using System.Linq; 5 using System.Linq.Expressions; 6 7 namespace C01.ZRF.DAL 8 { 9 using C01.ZRF.IDAL; 10 using IOC; 11 using System.Data.Entity; 12 13 public class BaseDAL<T>:IBaseDAL<T> where T:class 14 { 15 //1.创建EF上下文 16 // BaseDBContext db = new BaseDBContext(); 17 DbContext db = DBContextFactory.GetDbContext(); 18 19 #region 0.0 批量更新EF容器数据到数据库 +int SaveChanges() 20 /// <summary> 21 /// 0.0 批量更新EF容器数据到数据库 22 /// </summary> 23 /// <returns>返回受影响行数</returns> 24 public int SaveChanges() 25 { 26 return db.SaveChanges(); 27 } 28 #endregion 29 30 #region 1.0 新增方法 +void Add(T model) 31 /// <summary> 32 /// 1.0 新增方法 33 /// </summary> 34 /// <param name="model"></param> 35 public void Add(T model) 36 { 37 //1.直接通过EF上下文的 Set方法 获取一个 针对于 T类 做操作的 DbSet对象 38 //var dbSet = db.Set<T>(); 39 //dbSet.Add(model); 40 db.Set<T>().Add(model); 41 } 42 #endregion 43 44 #region 2.0 删除方法 +void Delete(T model) 45 /// <summary> 46 /// 2.0 删除方法 47 /// </summary> 48 /// <param name="model"></param> 49 public void Delete(T model) 50 { 51 DbEntityEntry entry = db.Entry<T>(model); 52 entry.State = System.Data.Entity.EntityState.Deleted; 53 } 54 #endregion 55 56 #region 2.1 条件删除方法 +void DeleteBy(System.Linq.Expressions.Expression<Func<T, bool>> delWhere) 57 /// <summary> 58 /// 2.1 条件删除方法 59 /// </summary> 60 /// <param name="delWhere">要删除的元素查询条件</param> 61 public void DeleteBy(System.Linq.Expressions.Expression<Func<T, bool>> delWhere) 62 { 63 var delList = db.Set<T>().Where(delWhere); 64 foreach (T model in delList) 65 { 66 Delete(model); 67 } 68 } 69 #endregion 70 71 #region 3.0 修改实体 + void Modify(T model, params string[] propertyNames) 72 /// <summary> 73 /// 3.0 修改实体 74 /// </summary> 75 /// <param name="model"></param> 76 /// <param name="propertyNames"></param> 77 public void Modify(T model, params string[] propertyNames) 78 { 79 DbEntityEntry entry = db.Entry<T>(model); 80 entry.State = System.Data.Entity.EntityState.Unchanged; 81 foreach (string proName in propertyNames) 82 { 83 entry.Property(proName).IsModified = true; 84 } 85 } 86 #endregion 87 88 #region 4.0 查询方法 +IQueryable<T> Where(Expression<Func<T, bool>> whereLambda) 89 /// <summary> 90 /// 4.0 查询方法 91 /// </summary> 92 /// <param name="whereLambda"></param> 93 /// <returns></returns> 94 public IQueryable<T> Where(Expression<Func<T, bool>> whereLambda) 95 { 96 return db.Set<T>().Where(whereLambda); 97 } 98 #endregion 99 100 #region 4.1 查询方法 -带排序 +IQueryable<T> WhereOrder<TKey> 101 /// <summary> 102 /// 4.1 查询方法 -带排序 103 /// </summary> 104 /// <typeparam name="TKey"></typeparam> 105 /// <param name="whereLambda"></param> 106 /// <param name="keySelector">u=></param> 107 /// <param name="isAsc"></param> 108 /// <returns></returns> 109 public IQueryable<T> WhereOrder<TKey>(Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> keySelector, bool isAsc = true) 110 { 111 if (isAsc) 112 return db.Set<T>().Where(whereLambda).OrderBy(keySelector); 113 else 114 return db.Set<T>().Where(whereLambda).OrderByDescending(keySelector); 115 } 116 #endregion 117 118 #region 4.2 查询方法 -带Include +IQueryable<T> WhereInclude 119 /// <summary> 120 /// 4.2 查询方法 -带Include 121 /// </summary> 122 /// <param name="whereLambda"></param> 123 /// <param name="includePropertyNames">要进行连接查询的 属性名</param> 124 /// <returns></returns> 125 public IQueryable<T> WhereInclude(Expression<Func<T, bool>> whereLambda, params string[] includePropertyNames) 126 { 127 DbQuery<T> dbQuery = db.Set<T>(); 128 foreach (string includeName in includePropertyNames) 129 { 130 dbQuery = dbQuery.Include(includeName); 131 } 132 return dbQuery.Where(whereLambda); 133 134 //DbQuery<T> dbSet = (DbQuery<T>)db.Set<T>().Where(whereLambda); 135 //foreach (string includeName in includePropertyNames) 136 //{ 137 // dbSet = dbSet.Include(includeName); 138 //} 139 //return dbSet; 140 } 141 #endregion 142 143 #region 4.3 查询方法 -带Include 和 排序 +IQueryable<T> WhereInclude<TKey> 144 /// <summary> 145 /// 4.3 查询方法 -带Include 和 排序 146 /// </summary> 147 /// <typeparam name="TKey"></typeparam> 148 /// <param name="whereLambda"></param> 149 /// <param name="keySelector"></param> 150 /// <param name="isAsc"></param> 151 /// <param name="includePropertyNames"></param> 152 /// <returns></returns> 153 public IQueryable<T> WhereInclude<TKey>(Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> keySelector, bool isAsc = true, params string[] includePropertyNames) 154 { 155 DbQuery<T> dbQuery = db.Set<T>(); 156 if (includePropertyNames != null && includePropertyNames.Length > 0) 157 { 158 foreach (string includeName in includePropertyNames) 159 { 160 dbQuery = dbQuery.Include(includeName); 161 } 162 } 163 IQueryable<T> query = dbQuery.Where(whereLambda); 164 if (isAsc) 165 return query.OrderBy(keySelector); 166 else 167 return query.OrderByDescending(keySelector); 168 } 169 #endregion 170 171 #region 4.4 查询方法 - 分页+Include+排序 + void WherePaged<TKey> 172 /// <summary> 173 /// 4.4 查询方法 - 分页+Include+排序 174 /// </summary> 175 /// <typeparam name="TKey"></typeparam> 176 /// <param name="pagedData"></param> 177 /// <param name="whereLambda"></param> 178 /// <param name="keySelector"></param> 179 /// <param name="isAsc"></param> 180 /// <param name="includePropertyNames"></param> 181 public IEnumerable<T> WherePaged<TKey>(int PageIndex, int PageSize, out int totalCount, Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> keySelector, bool isAsc = true, params string[] includePropertyNames) 182 { 183 //0.获取 要操作的 数据表 对应的查询对象 184 DbQuery<T> dbQuery = db.Set<T>(); 185 if (includePropertyNames != null && includePropertyNames.Length > 0) 186 { 187 foreach (string includeName in includePropertyNames) 188 { 189 dbQuery = dbQuery.Include(includeName); 190 } 191 } 192 193 IOrderedQueryable<T> orderQuery = null; 194 //2.排序 195 if (isAsc) { orderQuery = dbQuery.OrderBy(keySelector); } 196 else { orderQuery = dbQuery.OrderByDescending(keySelector); } 197 //3.分页查询 198 var list = orderQuery.Where(whereLambda).Skip((PageIndex - 1) * PageSize).Take(PageSize).ToList(); 199 //4.获取总行数 200 totalCount = orderQuery.Where(whereLambda).Count(); 201 return list; 202 } 203 #endregion 204 205 #region 4.5 查询方法 QueryBySql(string sql, params System.Data.SqlClient.SqlParameter[] ps) SQl语句的查询方法 206 public IQueryable<T> QueryBySql(string sql, params System.Data.SqlClient.SqlParameter[] ps) 207 { 208 return db.Database.SqlQuery<T>(sql, ps).AsQueryable(); 209 } 210 #endregion 211 } 212 }
View Code
T4模板生成的代码如下:
<#@ template language="C#" debug="false" hostspecific="true"#> <#@ include file="EF.Utility.CS.ttinclude"#> <#@ output extension=".cs"#> <# CodeGenerationTools code = new CodeGenerationTools(this); MetadataLoader loader = new MetadataLoader(this); CodeRegion region = new CodeRegion(this, 1); MetadataTools ef = new MetadataTools(this); string inputFile1 = @"E:\Temp\test01\3LaySolution\C10.ZRF.Model\Model1.edmx"; EdmItemCollection ItemCollection1 = loader.CreateEdmItemCollection(inputFile1); string namespaceName = code.VsNamespaceSuggestion(); EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this); #> using System; using System.Collections.Generic; using System.Linq; using System.Text; using C01.ZRF.IDAL; using C10.ZRF.Model; namespace C01.ZRF.DAL { <# foreach (EntityType entity in ItemCollection1.GetItems<EntityType>().OrderBy(e => e.Name)) { #> public partial class <#=entity.Name#>_DAL : BaseDAL<<#=entity.Name#>>,I<#=entity.Name#>_DAL{ } <#}#> }
View Code
如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using C01.ZRF.IDAL; using C10.ZRF.Model; namespace C01.ZRF.DAL { public partial class BuyCar_DAL : BaseDAL<BuyCar>,IBuyCar_DAL{ } public partial class Menu_DAL : BaseDAL<Menu>,IMenu_DAL{ } public partial class Product_DAL : BaseDAL<Product>,IProduct_DAL{ } public partial class Role_DAL : BaseDAL<Role>,IRole_DAL{ } public partial class roleMenu_DAL : BaseDAL<roleMenu>,IroleMenu_DAL{ } public partial class uerRole_DAL : BaseDAL<uerRole>,IuerRole_DAL{ } public partial class User_DAL : BaseDAL<User>,IUser_DAL{ } }
View Code
3:IBLL
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Linq.Expressions; 5 using System.Text; 6 using System.Threading.Tasks; 7 8 namespace C01.ZRF.IBLL 9 { 10 public interface IBaseBLL<T>where T:class 11 { 12 int SaveChanges(); 13 14 void Add(T model); 15 16 void Delete(T model); 17 18 void DeleteBy(Expression<Func<T, bool>> delWhere); 19 20 void Modify(T model, params string[] propertyNames); 21 22 IQueryable<T> Where(Expression<Func<T, bool>> whereLambda); 23 24 IQueryable<T> WhereOrder<TKey>(Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> keySelector, bool isAsc = true); 25 26 IQueryable<T> WhereInclude(Expression<Func<T, bool>> whereLambda, params string[] includePropertyNames); 27 28 IQueryable<T> WhereInclude<TKey>(Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> keySelector, bool isAsc = true, params string[] includePropertyNames); 29 30 IEnumerable<T> WherePaged<TKey>(int PageIndex, int PageSize, out int totalCount, Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> keySelector, bool isAsc = true, params string[] includePropertyNames); 31 32 IQueryable<T> QueryBySql(string sql, params System.Data.SqlClient.SqlParameter[] ps); 33 } 34 }
View Code
T4代码生成器:
<#@ template language="C#" debug="false" hostspecific="true"#> <#@ include file="EF.Utility.CS.ttinclude"#> <#@ output extension=".cs"#> <# CodeGenerationTools code = new CodeGenerationTools(this); MetadataLoader loader = new MetadataLoader(this); CodeRegion region = new CodeRegion(this, 1); MetadataTools ef = new MetadataTools(this); string inputFile1 = @"E:\Temp\test01\3LaySolution\C10.ZRF.Model\Model1.edmx"; EdmItemCollection ItemCollection1 = loader.CreateEdmItemCollection(inputFile1); string namespaceName = code.VsNamespaceSuggestion(); EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this); #> using System; using System.Collections.Generic; using System.Linq; using System.Text; using C10.ZRF.Model; namespace C01.ZRF.IBLL { <# foreach (EntityType entity in ItemCollection1.GetItems<EntityType>().OrderBy(e => e.Name)) { #> public partial interface I<#=entity.Name#>_BLL : IBaseBLL<<#=entity.Name#>>{ } <#}#> }
View Code
效果如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using C10.ZRF.Model; namespace C01.ZRF.IBLL { public partial interface IBuyCar_BLL : IBaseBLL<BuyCar>{ } public partial interface IMenu_BLL : IBaseBLL<Menu>{ } public partial interface IProduct_BLL : IBaseBLL<Product>{ } public partial interface IRole_BLL : IBaseBLL<Role>{ } public partial interface IroleMenu_BLL : IBaseBLL<roleMenu>{ } public partial interface IuerRole_BLL : IBaseBLL<uerRole>{ } public partial interface IUser_BLL : IBaseBLL<User>{ } }
View Code
4:BLL
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 5 namespace C01.ZRF.BLL 6 { 7 using C01.ZRF.IBLL; 8 using C01.ZRF.IDAL; 9 using System.Data.SqlClient; 10 public partial class BaseBLL<T> : IBaseBLL<T> where T : class 11 { 12 protected IBaseDAL<T> basedal; 13 public void Add(T model) 14 { 15 basedal.Add(model); 16 } 17 18 public void Delete(T model) 19 { 20 basedal.Delete(model); 21 } 22 23 public void DeleteBy(System.Linq.Expressions.Expression<Func<T, bool>> delWhere) 24 { 25 basedal.DeleteBy(delWhere); 26 } 27 28 public void Modify(T model, params string[] propertyNames) 29 { 30 basedal.Modify(model, propertyNames); 31 } 32 33 public IQueryable<T> QueryBySql(string sql, params SqlParameter[] ps) 34 { 35 return basedal.QueryBySql(sql, ps); 36 } 37 38 public int SaveChanges() 39 { 40 return basedal.SaveChanges(); 41 } 42 43 public IQueryable<T> Where(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda) 44 { 45 return basedal.Where(whereLambda); 46 } 47 48 public IQueryable<T> WhereInclude(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda, params string[] includePropertyNames) 49 { 50 return basedal.WhereInclude(whereLambda, includePropertyNames); 51 } 52 53 public IQueryable<T> WhereInclude<TKey>(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda, System.Linq.Expressions.Expression<Func<T, TKey>> keySelector, bool isAsc = true, params string[] includePropertyNames) 54 { 55 return basedal.WhereInclude<TKey>(whereLambda, keySelector, isAsc, includePropertyNames); 56 } 57 58 public IQueryable<T> WhereOrder<TKey>(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda, System.Linq.Expressions.Expression<Func<T, TKey>> keySelector, bool isAsc = true) 59 { 60 return basedal.WhereOrder<TKey>(whereLambda, keySelector, isAsc); 61 } 62 63 public IEnumerable<T> WherePaged<TKey>(int PageIndex, int PageSize, out int totalCount, System.Linq.Expressions.Expression<Func<T, bool>> whereLambda, System.Linq.Expressions.Expression<Func<T, TKey>> keySelector, bool isAsc = true, params string[] includePropertyNames) 64 { 65 return basedal.WherePaged<TKey>(PageIndex, PageSize, out totalCount, whereLambda, keySelector, isAsc, includePropertyNames); 66 } 67 } 68 }
View Code
T4模板生成器:
<#@ template language="C#" debug="false" hostspecific="true"#> <#@ include file="EF.Utility.CS.ttinclude"#> <#@ output extension=".cs"#> <# CodeGenerationTools code = new CodeGenerationTools(this); MetadataLoader loader = new MetadataLoader(this); CodeRegion region = new CodeRegion(this, 1); MetadataTools ef = new MetadataTools(this); string inputFile1 = @"E:\Temp\test01\3LaySolution\C10.ZRF.Model\Model1.edmx"; EdmItemCollection ItemCollection1 = loader.CreateEdmItemCollection(inputFile1); string namespaceName = code.VsNamespaceSuggestion(); EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this); #> using System; using System.Collections.Generic; using System.Linq; using System.Text; using C10.ZRF.Model; using C01.ZRF.IBLL; using C01.ZRF.IDAL; namespace C01.ZRF.BLL { <# foreach (EntityType entity in ItemCollection1.GetItems<EntityType>().OrderBy(e => e.Name)) { #> public partial class <#=entity.Name#>_BLL : BaseBLL<<#=entity.Name#>>,I<#=entity.Name#>_BLL{ I<#=entity.Name#>_DAL dal; public <#=entity.Name#>_BLL(I<#=entity.Name#>_DAL dal){ this.dal=dal; base.basedal=dal; } } <#}#> }
View Code
效果如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace C01.ZRF.BLL 8 { 9 using C10.ZRF.Model; 10 using C01.ZRF.IBLL; 11 using C01.ZRF.IDAL; 12 public partial class RoleBLL : BaseBLL<Role>, IRole_BLL 13 { 14 IRole_DAL dal; 15 public RoleBLL(IRole_DAL dal) { 16 this.dal = dal; 17 base.basedal = dal; 18 } 19 } 20 }
View Code
5:AutoFac配置文件内容
1 using Autofac; 2 using Autofac.Integration.Mvc; 3 using System.Reflection; 4 5 namespace WebApplication1 6 { 7 public class AutoFacConfig 8 { 9 public static void Register() 10 { 11 //1.0 创建一个autofac的容器创建者对象 12 var builder = new ContainerBuilder(); 13 14 //2.0 告诉autofac控制器类所存储的程序集是谁 15 Assembly controllerAss = Assembly.Load("WebApplication1"); 16 builder.RegisterControllers(controllerAss); 17 18 19 //3.0 将仓储层中的所有的类实例化以其接口的形式存储起来 20 Assembly dalAss = Assembly.Load("C01.ZRF.DAL"); 21 builder.RegisterTypes(dalAss.GetTypes()).AsImplementedInterfaces(); 22 23 //4.0 将业务逻辑层中的所有的类实例化以其接口的形式存储起来 24 Assembly bllAss = Assembly.Load("C01.ZRF.BLL"); 25 builder.RegisterTypes(bllAss.GetTypes()).AsImplementedInterfaces(); 26 27 //5.0 告诉MVC底层控制器的对象创建工作被autofac替代 28 //5.0.1 创建一个真正的autofac工作容器 29 var c = builder.Build(); 30 31 //5.0.2 将auto发出工作容器替换MVC底层 32 System.Web.Mvc.DependencyResolver.SetResolver(new AutofacDependencyResolver(c)); 33 } 34 } 35 }
View Code
配置后再去Global.asax 全局文件里面注册即可:
1 protected void Application_Start() 2 { 3 AreaRegistration.RegisterAllAreas(); 4 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 5 RouteConfig.RegisterRoutes(RouteTable.Routes); 6 BundleConfig.RegisterBundles(BundleTable.Bundles); 7 AutoFacConfig.Register();//------ 8 9 }
View Code
6:Web端来调用:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web.Mvc; 5 6 namespace WebApplication1.Controllers 7 { 8 using C01.ZRF.IBLL; 9 using C10.ZRF.Model.ModelView; 10 using COMMOM; 11 using C10.ZRF.Model.Filter; 12 using System.Threading.Tasks; 13 using C10.ZRF.Model; 14 15 // [WebApplication1._Filters.ZrfComparess] 16 public class HomeController : Controller 17 { 18 public ActionResult DoCombresTest() { 19 return View(); 20 } 21 22 #region MyRegion 23 IBuyCar_BLL bll; 24 public HomeController(IBuyCar_BLL bll) 25 { 26 this.bll = bll; 27 } 28 // GET: Home 29 public ActionResult Index() 30 { 31 ViewBag.car = bll.Where(c => c.cid == 6).FirstOrDefault().pcount; 32 ViewBag.time = "时间是=" + DateTime.Now.ToString(); 33 return View(); 34 } 35 } 36 }
View Code
如有疑问或者错误的地方,请跟帖,本人会第一时间答复以及相互学习,谢谢!个人会不断的上传自己的学习心得!
好了今天就先到这里,下次有时间再更新,如果存在不合理的地方,欢迎大家多多指教留言!!!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/64020.html