这一篇,来简单介绍一下如何在CAD已有的图形中查找实体。前面的内容一直都在说如何在图形当中添加实体。但是,在真正开发的过程中,只掌握如何添加是不够的。应该说对CAD数据库操作和对其他数据库的操作大同小异,除了增加之外,还要有删除、修改、查询等基本操作,也就是程序员们经常说的增删改查,对应SQL的语法中的INSERT,DELETe,UPDATE和SELECT语句,那么今天我们就来说说在CAD中如何查找,在接下来的篇章里探讨如何修改和删除图形。本篇的内容会涉及到C#语言中泛型的相关知识,在前面C#学习笔记系列简单讲过。
我们使用.NET平台为我们提供的语言集成查询,也就是LINQ完成这一篇内容的任务,LINQ全称是Language-Integrated Query ,在C#3.0以及visual studio2008版本及以上可以使用。它将数据库查询的语句集成到.NET平台当中,使得编程人员无需了解SQL的语法也可以进行简单的查询,使用起来十分方便,而且他还分为查询语法和方法语法,两种语法完全等效,分别为熟悉SQL的人以及熟悉C#泛型和委托的人准备,如果都不太熟悉,也比较好上手。
我们的实例从这里展开:在CAD图形中有9个圆,排布没有规律,半径分别为100,200…900,这里代码的过程是:先行封装一个方法,让我们获取图形中所有的圆,再对获取圆的结果进行LINQ查询,获得我们想要的信息并输出与编辑栏
我们封装的代码是要按照类型进行查询,而CAD中有很多实体类型,那么这里正如C#学习笔记中所说,类型不确定,可能引起成员膨胀的语境,使用泛型是十分正确的选择,函数声明如下:
它是一个泛型方法,返回值类型待特化,且需要是Entity类的子类,我们在函数调用时,将类型特化为圆,返回值即为一个List,这个list包含图形中所有的圆,特化为直线,就返回图形中所有的直线,其他类型同理,该方法作为CAD数据库的拓展方法。在方法体内的逻辑过程大致如下:首先声明一个列表用于返回函数所查找的类型;然后获取泛型T的类型;构建过滤器,选择所有符合条件的实体,然后将实体加入列表返回,代码如下:
//按照类型查找实体的泛型方法public static List GetEntsFromDB(this Database db,OpenMode mode) where T:Entity{ Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; //声明一个列表用于返回函数所查找的类型 List ents = new List(); //获取泛型T的类型 string dxfName = RXClass.GetClass(typeof(T)).DxfName; //构建过滤器 TypedValue[] values = { new TypedValue((int)DxfCode.Start, dxfName) }; SelectionFilter filter = new SelectionFilter(values); //选择所有符合条件的实体 PromptSelectionResult selected = ed.SelectAll(filter); if (selected.Status==PromptStatus.OK) { //遍历所有符合条件的实体 foreach (var id in selected.Value.GetObjectIds()) { //将实体转化成object之后再转化为T T t = (T)(object)id.GetObject(mode, false); //将实体加入列表 ents.Add(t); } } return ents; }
这里需要注意的是,在参数列表中有一个OpenMode就是读写模式,当我们只用于查询的时候,设置为读模式,需要修改或删除的时候为写模式,本篇我们的内容只涉及查询,所以使用读模式,这个模式是一个枚举类型,这里还可以有这样一个操作,让这个方法默认为读模式,那么就重载这个方法,使其默认为读模式,代码如下:
//重载按类型查找实体的函数,使其可以将读取模式作为默认public static List GetEntsFromDB(this Database db) where T : Entity{ return GetEntsFromDB(db,OpenMode.ForRead);}
接下来,使用方法,我们在类库中注册命令FindCircle,在事务处理中,完成目标:
上面的语句就是调用按类型查找的泛型方法,在调用语句中,将类型特化为圆,然后对查找的结果进行查询,获取圆的属性,也就是我们要打在编辑栏上的字符串,整个过程的代码如下:
[CommandMethod("FindCircle")]public static void FindCircle(){ //数据库和编辑栏 Database db = HostApplicationServices.WorkingDatabase; Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; //事务处理 using (Transaction trans=db.TransactionManager.StartTransaction()) { //调用方法,获取数据库中所有的圆 var circles = db.GetEntsFromDB(); //LINQ查询,获取圆的属性 var messages = (from c in circles select $"半径:{c.Radius};圆心X坐标:{c.Center.X};圆心Y坐标{c.Center.Y}").ToList(); //遍历查询结果 foreach (var message in messages) { ed.WriteMessage(message+"n"); } //事务提交 trans.Commit(); }}
运行结果如视频所示:
这一篇就先讲到这里,在下一篇中,我们进一步讨论LINQ的语句,介绍更多的LINQ子句,看看查询语法和方法语法都长什么样子,在接下来的修改删除相关篇章当中,LINQ会继续登场让我们有的放矢,到时会有更多的子句和操作。如果有什么问题或者是批评建议,欢迎在公众号内留言,谢谢!



