雪山飞狐_lzh 发表于 2010-12-6 19:53:30

本帖最后由 lzh741206 于 2010-12-6 19:54 编辑

哎,你不能把一个实体两次重复的加入数据库
这里加入一次
                ObjectId c1 = AddCircle(new Point3d(0, 0, 0), 10);
                ObjectId c2 = AddCircle(new Point3d(0, 0, 0), 15);

接着又加了一次
                CreateBlockDef("Test", objs);

上一个帖子的代码我不是直接贴了吗,汗

chpmould 发表于 2010-12-6 19:56:55

你可以帮我调通吗?绘制圆的方式还是按以下方式...
ObjectId c1 = AddCircle(new Point3d(0, 0, 0), 10);
ObjectId c2 = AddCircle(new Point3d(0, 0, 0), 15);

河伯 发表于 2010-12-6 20:30:06

Linq是个好东西,还没来得及研究哪。不过,这个好像是Lambda表达式,和Linq没关系吧?
Ids.Cast(Of ObjectId).ToList().ForEach(Sub(id) objs.Add(id.GetObject(OpenMode.ForRead)))

雪山飞狐_lzh 发表于 2010-12-6 20:59:19

Cast、ToList就是System.Linq的扩展了
Linq和Lambda结合的还是挺多的

不过我的想法是
            ids
            .Cast<ObjectId>()
            .Select(id => id.GetObject(OpenMode.ForRead));
只返回一个查询,这个用到的更多些

河伯 发表于 2010-12-6 21:42:47

      Dim lstObj As New List(Of T)
      Dim objs As New DBObjectCollection
      Using Trans As Transaction = db.TransactionManager.StartTransaction
            Array.ForEach(Ids, Sub(Id) objs.Add(Id.GetObject(OpenMode.ForRead)))
            lstObj = objs.OfType(Of T).ToList
            Trans.Commit()
      End Using
很好!前面函数又改了一下,果然简洁不少,看来用.NET真要有点新思维。

雪山飞狐_lzh 发表于 2010-12-6 22:02:30

本帖最后由 lzh741206 于 2010-12-6 22:08 编辑

你还是写复杂了,呵呵
建议的方式,在子函数里不要新建事务,如果处理的实体较多,每开一个事务就会占耗时
正确的做法是传入事务作为参数,

      
      public void tttt()
      {
            var db = HostApplicationServices.WorkingDatabase;
            var doc = Application.DocumentManager.GetDocument(db);
            var ed = doc.Editor;

            using (Transaction tr = doc.TransactionManager.StartTransaction())
            {

                ObjectIdCollection ids = new ObjectIdCollection();
                var cirs = GetEntitys<Circle>(tr, ids.Cast<ObjectId>());

            }
            
      }

      public IEnumerable<T> GetEntitys<T>(Transaction tr, IEnumerable<ObjectId> ids) where T : DBObject
      {
            return
                ids
                .Select(id => tr.GetObject(id, OpenMode.ForRead))
                .OfType<T>();
      }

河伯 发表于 2010-12-6 22:28:45

方法不错,可借鉴。其实以我的经验,代码的可读性比性能更重要,呵呵。
参数多了,代码长了,经常是隔段时间自己都看不懂了,不容易维护。

雪山飞狐_lzh 发表于 2010-12-6 22:37:29

你说的是一个方面
还有情况是不能把事务放到子函数的,
比如对内存数据库的操作
即Database = new Database()的情况,这时用你的函数会出错的
而且多事务操作不光耗时,有时会产生莫名其妙的错误
传入事务作为参数的方式在kean的代码里经常会看到的,
应该算是Autodesk推荐的方式吧

河伯 发表于 2010-12-6 23:11:27

事物耗时的问题,我已注意到。具体的实现里面,并没有嵌套事务。当需要多重操作,通过重载函数来完成的。
前面的子函数,都是不同类里面的成员,并无主次之分,如果把事物作为参数,反而容易搞乱逻辑。
当然,这些还只用.NET的初步感觉,未来有N多代码要迁移,随着研习的深入,希望找到一个好的设计模式。

雪山飞狐_lzh 发表于 2010-12-6 23:23:43

本帖最后由 lzh741206 于 2010-12-6 23:29 编辑

正确,这个只有做多了才会感觉到
我以前在论坛贴过的DBTransaction类算是这方面我自己的解决方案吧
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=76123&extra=%26page%3D1&page=1
这个类的调用代码可以看看这里:
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=75701
各人有个人的想法,不强求,你说的重载函数的方式我看就不错,呵呵



页: 1 [2] 3
查看完整版本: 集合对象的相互转换