C# 动态建类简单用例

动态建类优点

1、多数据库支持完美,多库必备,支持json和自定义类型,还可以可以用来建表,CRUD等 (纯字典是做不到的)

2、支持类的所有额外功能 ,比如AOP等、过滤器和导航等等

注意点:

相同的表创建的Type需要缓存起来,可以用自带的也可以你自已缓存,如果无限创建那么可能会存在内存泄露风险

一、动态建类+CRUD

   var typeBilder = db.DynamicBuilder().CreateClass("table1", new SugarTable(){});
             
   //可以循环添加列
   typeBilder.CreateProperty("Id",typeof(int),new SugarColumn(){IsPrimaryKey=true,IsIdentity=true});
   typeBilder.CreateProperty("Name", typeof(string), new SugarColumn() { });
   
   typeBilder.WithCache(); //缓存Key 表名+字段名称相加
   
   //创建类
   var type = typeBilder.BuilderType();  

   
   //创建表
   db.CodeFirst.InitTables(type); //建表属性API看迁移  
    
    //根据字典转成类对象
    var dic=new Dictionary<string,object>(){{ "Id", 1 },{ "Name", "jack" }};         
    var value= db.DynamicBuilder().CreateObjectByType(type,dic);//可以是List<字典>
    //可以是List<Dictionary<string, object>()
     
    db.InsertableByObject(value).ExecuteCommand();
    db.UpdateableByObject(value).ExecuteCommand();
    db.DeleteableByObject(value).ExecuteCommand();
    db.StorageableByObject(value).ExecuteCommand();//插入或者更新
    //查询 带有类功能 5.1.4.84 
    // API和无实体查询类似
    db.QueryableByObject(type).ToList();

二、动态建类+分表操作

 var type = db.DynamicBuilder().CreateClass("table1", new SugarTable()
            {
            },null,null,new SplitTableAttribute(SplitType.Day))
            
  .CreateProperty("Id",typeof(int),new SugarColumn(){IsPrimaryKey=true,IsIdentity = true })
  .CreateProperty("Time", typeof(DateTime), new SugarColumn() { },true)//true表式分表字符
   .WithCache() //缓存起来根据表名和字段名组合的KEY     
  .BuilderType();
  
   //创建表
   db.CodeFirst.InitTables(type); //建表属性API看迁移  
      
  db.InsertableByObject(value).SpiltTable().ExecuteCommand();
  db.UpdateableByObject(value).SpiltTable().ExecuteCommand();
  db.DeleteableByObject(value).SpiltTable().ExecuteCommand();
  
  //查询 需要高版本sqlsugar
  db.QueryableByObject(type).SpiltTable().ToList();


三、复杂构造

 3.1 继承基类或者接口

如果表已存在,并且不是CodeFirst建的请把主删了,否则可能因约束建表失败,是一种对原本的保护

 var type = db.DynamicBuilder().CreateClass("table12", new SugarTable(){}
            ,typeof(Order)//继承Order类
            )
    .CreateProperty("yyy", typeof(string), new SugarColumn() { })
     //.WithCache() 缓存起来根据表名和字段名组合的KEY     
    .BuilderType();
db.CodeFirst.InitTables(type);

建表所有参数

public DynamicProperyBuilder CreateClass(
string entityName, 
 SugarTable table=null, 
 Type baseType = null, //基类
 Type[] interfaces = null,//接口
 SplitTableAttribute splitTableAttribute=null)

 3.2 属性是当前类 (树型

请升级到:5.1.4.125-preview12+

//假设类为Tree那么我Child就是List<Tree> 这个时候就需要用下面的固定类型代表自已的集合
propertyType = typeof(DynamicOneselfTypeList);//List<当前类>

//假设类为Tree那么我有个Parent属性为Tree 这个时候我就需要下面的固定类代表当前类
propertyType = typeof(DynamicOneselfType);//当前类

 3.3 导航: A里有B,B里面有A

请升级到:SqlSugarCore 5.1.4.157-preview10+

var a = db.DynamicBuilder().CreateClass("a")
    .CreateProperty("aid", typeof(int))
    .CreateProperty("bid", typeof(int))
    .CreateProperty("bItem", typeof(SqlSugar.NestedObjectType),navigate: new Navigate(NavigateType.OneToOne,nameof(bid)));

var b = db.DynamicBuilder().CreateClass("b")
    .CreateProperty("bid", typeof(int))
    .CreateProperty("aList", typeof(SqlSugar.NestedObjectTypeList), navigate: new Navigate(NavigateType.OneToMany,nameof(A.bid)))
    .WithCache()//存入缓存防止多次创建引起内存泄露
    .BuilderTypes(a);

var typea = b.Item1;
var typeb = b.Item2;

//nameof说明
nameof(bid)其实就是 "bid"
nameof(A.bid) 其实就是 "bid"
//我上面用nameof做示例没直接写字符串是让你看懂原理,直接填字符串就行了

更多导航属性要看5.3

四、动态类如何加索引

 Db.DbMaintenance.CreateIndex(....)
 //isUnique 是区分普通索引还是唯一索引
 bool CreateIndex(string tableName, string [] columnNames, bool isUnique=false);
 bool CreateIndex(string tableName, string[] columnNames, string IndexName, bool isUnique = false);

五、导航 

5.1 导航过滤  5.1.4.107-preview14

  配置Dynamic.Core 看标题13 https://www.donet5.com/Home/Doc?typeId=1184     

var list5=db.QueryableByObject(EntityType).Where("it", $"it=>it.Address.Id=={1}").ToList();
var list6=db.QueryableByObject(EntityType).Where("it", $"it=>it.Pers.Any(s=>s.AddressId==it.Id)").ToList();

5.2 导航填充

 var list=db.QueryableByObject(EntityType)
                 .Includes("A1","A2")//A1下面有A2 
                 .Includes("B1")
                 .ToList();

5.3 动态创建导航 

请升级:5.1.4.110-preview02+

 var db = NewUnitTest.Db;
 var typeBilder = db.DynamicBuilder().CreateClass("table1dfafa1231", new SugarTable() { });

 //可以循环添加列
 typeBilder.CreateProperty("Id", typeof(int), new SugarColumn(){ IsPrimaryKey = true, IsIdentity = true });
 typeBilder.CreateProperty("Name", typeof(string), new SugarColumn() { });
 //一对一
 typeBilder.CreateProperty("OrderInfo",typeof(Order), 
 navigate: new Navigate(NavigateType.OneToOne, "Id" ));//和导航查询一配置法
 
 //一对多
 typeBilder.CreateProperty("OrderInfos", typeof(List<Order>), 
 navigate: new Navigate(NavigateType.OneToMany, nameof(Order.Id)));//和导航查询一配置法
 typeBilder.WithCache(); //缓存Key 表名+字段名称相加


 //创建类
 var type = typeBilder.BuilderType();

 //建表
 db.CodeFirst.InitTables(type);

 //设置动态表达式
 StaticConfig.DynamicExpressionParserType = typeof(DynamicExpressionParser);

 var dic=  new Dictionary<string,object> { { "Name", "jack" } };
 var insertObj = db.DynamicBuilder().CreateObjectByType(type, dic);
 db.InsertableByObject(insertObj).ExecuteCommand();

 var list=db.QueryableByObject(type)
     .Where("it", $"it=>it.OrderInfo.Id==1")
     .Where("it",$"it=>it.OrderInfos.Any()")
     .ToList();

 var list2 = db.QueryableByObject(type)
   .Includes("OrderInfo")
   .Includes("OrderInfos")
   .ToList();

六、字符串表达式更多用法

.Where("it", $"it=>it.OrderInfo.Id==1")

https://www.donet5.com/Home/Doc?typeId=2569

七、清空缓存typeBilder.WithCache()

如果有存在修改,可以根据你创建的className进行清空

//删除正常类
db.Utilities.RemoveCacheByLikeKey<Type>("className")
//删除(3.3讲解的那种情况)
db.Utilities.RemoveCacheByLikeKey<Tuple<Type, Type>>("className");


关闭
果糖网