Categories

Links

重新启动activecontent 开发

约一年前 ,由于各种原因,我放弃了activecontent 的开发,因为基于asp的开发受限太多,而升级到asp.net 却又不够足够吸引力而且过于笨重(我们交付过一个.net和asp互操作的升级版本,这个反响并不好)。

在拥抱动态语言后的今天,我决定重新启动activecontent的开发。我相信这段时间的思考足以让新的系统更加成熟和人性化,而python/django 也给了我足够发挥的天空。

我们将打造一个 web 2.0时代的内容系统,解决您日益复杂的建站和维护问题。如果您有兴趣,欢迎参与我们的开发过程,您的意见和参与将是我们宝贵的财富。

联系我们 :

gtalk/mail jiangjianxiao@gmail.com
msn  jiangjianxiao@msn.com

注 activecontent 是暂用名

[2007-10-27 17:50:14 | Author:jiangjianxiao ] [] 5 comments

ironruby 终于发布了第一个版本

下面是几个链接

First Look at IronRuby
http://weblogs.asp.net/scottgu/archive/2007/07/23/first-look-at-ironruby.aspx

里面的下载地址访问不了,不过可以下载下面这个

ironruby on mono

http://sparcs.kaist.ac.kr/~tinuviel/download/IronRuby/

 

刚才试了rbx 控制台,完成度不高 ,连hash都不支持,不过将代码放在rb文件中,用 rbx test.rb倒是正常的

这段代码通不过

dict=Hash.new(0)

dict['a']
puts dict['a']
dict['b']='this is rb'

puts dict['b']

这段代码也通不过

line="Microsoft Visual basic"

if line=~/basic/
  puts "has  basic"
end

同样,这两行也通不过

puts line.sub(/basic/,"test")
puts line.gsub(/basic/, "foxpro")

 区间不行(Range类型实际上是被支持的,但each 没有提供)

('a'..'e').each{  |char| print char}

没有upto方法
3.upto(6) { |i| print i}

inspect/to_s  todo

song=Song.new("bicyclops","Fleck",260)
print song.inspect
print song.to_s

 

 attr_reader 也是todo

 一些重要的方法没有提供,如 Object.methods,Object.private_methods,Object.protected_methods,Object.publish_methods,Module.instance_methods等这些与自省有关的重要方法

不想再试下去了

[2007-07-24 18:12:00 | Author:jiangjianxiao ] [] 1000 comments

在Windows Forms中应用linq to sql的一些建议

此文是我在项目中应用linq to sql 的一些总结, 它正在随项目进行不断修正中,这里应该没有最正确的一说

有两个决策会影响你的应用程序结构和编码

首先,你是否打算支持remoting或是webservice ,其次,你是否打算支持批量更新. 其中第一点尤为重要.

支持remoting/webservice的应用结构

项目通常划分为

myapplication.services  提供远程服务的调用
myapplication.models 依赖myapplication.services
myapplication.views 依赖myapplication.models
myapplication 启动应用

不支持remoting/webservice应用结构

myapplication.models  直接使用datacontext
myapplication.views 依赖myapplication.models
myapplication 启动应用

myapplication.models 通常有包括linq to sql 的数据类并分离类 ,所有的业务逻辑将在分离类中,并使用ddd 开发,或许你的应用程序现在不打算支持remoting/webservice,但需要考虑以后支持remoting/webservice,有以下几点建议

1. 在view层,确保只使用models 层提供的方法
2. 在view层,最好不使用关系
3.总是使用ToList,ToArray等返回的结果集

当使用关系导航时,虽然简洁,但依赖datacontext,因此在远程环境中windows forms比web环境更为糟糕, 因为web环境通常在一台机器上,还有个request范围可用 .

DataContext的使用建议

无论是否打算在remoting/webservice环境,保持在一次请求中使用和放弃DataContext是一个好的想法,如果你不想这样做,linq to sql 固有的问题也不会让使用一个长久的DataContext.比方说下面的代码(特别的,使用了自定义的关键字值

Department d=new Department();

d.Id="61";

db.Departments.Add(d);

db.SubmitChanges();

db.Departments.Remove(d);

db.SubmitChanges();

Department d2=new Department();

d2.Id="61";

db.Departments.Add(d2);

db.SubmitChanges() ;  //这里出现重复的关键字错误,注意这个错误不是由数据库 触发的,因为数据库中本来就已经把早先的61给删除了,这应该是datacontext内部的identity map 出错了

可以学习spring/spring.net 的template机制,创建一个DataContextTemplate类 , 让service引用这个类,如果不考虑remoting/webservice 也可以在entity基类 中并入DataContextTemplate的方法,前者的分离度会更高些,但总是需要确保entity类不会直接访问dataContext

下面是DataContextTemplate的接口设计
public delegate void DoInDataContext(DataContext db);
public delegate object DoInDataContextWithResult(DataContext db);

public interface DataContextTemplate{
    void  Find(DoInDataContext doInDataContext);
    IList<TEntity> GetObjects<TEntity>(DoInDataContextWithResult callback) where TEntity : class;
    TEntity GetObject<TEntity>(DoInDataContextWithResult callback) where TEntity : class;
    IList<TEntity> FindAll<TEntity>() where TEntity : class ;
    IList<TEntity> FindByLimit<TEntity>(int limit) where TEntity:class;
    TEntity FindById<TEntity>(System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate) where TEntity:class;
    IList<TEntity> FindRelationById<TEntity>(System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate) where TEntity:class;
    IList<TEntity> FindByCondition<TEntity>(string condition,string ob,params object[] conditionParams) where TEntity:class;
    void Execute(DoInDataContext  doInDataContext);
    void SubmitChanges(ChangeSet changeSet);
    ChangeSet GetChangeSet(Type type);

}


models的设计

下面总结一些共性的东西
1. parital 类应该实现IDataErrorInfo接口,建议将其实现为基类
2. 使用OnxxxChanging或是OnxxxChanged partial 方法进行数据验证
3. 使用OnxxxChanged partial method 进行关联更新
3. 如果不考虑远程,可在entity的基础类 中实现一个DataContextTemplate 的变量,如db,这样,子类就可以直接调用它
4. 以下是一些公共方法的签名,这些方法可以简单的借助DataContextTemplate来实现
FindAll 返回全部记录
FindById 返回该id的记录
FindByCondition 执行动态查询
FindByLimit 执行top查询
FindByRelation 执行关系端查询,Relation可用具体的关系端名来替代

范型方法例子(todo)

关系

在linq to sql 中,使用EntityRef,EntitySet来维系关系,这是因为关系端的获取可能有left outer join和lazy load等优化方式,当你放弃linq to sql的关系后 ,意味着你自己需要用传统的类型来做关系的管理.  其实,Table<Enttiy>.Attach适合远程这类环境,但 在实际的编程中,要么用要么不用,否则,编码没有一致性,会导致一些bug和以后的维护问题

 

 创建changeset

当使用批量更新并在每次需求间请求和放弃DataContext时,客户端维护自身的ChangeSet就相当重要,ChangeSet保存了新增,修改和删除的对象,在合适的时候,比方说用户点击保存时提交.
当新建,改变(可跟踪bindingSource的ListChanged事件),删除时,将改变的对象写入changeset

更新时,从changeset 取出 对象进行更新

更新顺序

同数据集一样,依次处理插入,更新,删除 ,并处理好关系端,不要过分依赖submitchanges的智能判断

适应ChangeSet的模型方法

master-detail记录
当使用批量更新时,master并没有保存到数据库中, 但detail 通常需要 master 的主键值

[2007-07-23 07:51:54 | Author:jiangjianxiao ] [] 1 comments

犯了一个低级错误

最近在.net framework june ctp 下工作,使用emacs和msbuild ,结果犯了一个低级错误,即如下代码并不像我想像的那样工作

if(String.IsNullOrEmpty(error))
    if( _errors.ContainsKey(propertyName))
        _errors.Remove(propertyName);
else
     _errors[propertyName]=error;

 

如果在vs.net 中,这段代码被自动格式化成

if(String.IsNullOrEmpty(error))
    if( _errors.ContainsKey(propertyName))
        _errors.Remove(propertyName);
    else
         _errors[propertyName]=error;

这样这个低级错误就很容易避免

本意应该是这个样子

if(String.IsNullOrEmpty(error)){
    if( _errors.ContainsKey(propertyName))
        _errors.Remove(propertyName);

}
else
     _errors[propertyName]=error;

另外,发现在entity中实现IDataErrorInfo ,当将列表绑定 到窗体上时,IDataErrorInfo.this方法被系统调用的次数好像过了头, 这是否同我现在所采用的界面模式有关(比方说bindingsource 同时绑定到一个grid view和一个detail view)上,以后再深究他

[2007-07-21 16:00:05 | Author:jiangjianxiao ] [] 1 comments

令我大跌眼睛的性能测试 -NET Framework 3.5 June 2007 ctp

一直以来,我以为linq to sql 的装载性能是稍差于datatable 的,早期的测试大约是慢1到2倍,测试的记录大概是6千多.

今天早晨,在 june 2007 ctp 上的测试让我大吃一惊, 我有一个大约7万多条的报价单明细表 ,这个表我用ibatis 返回entity大约要18秒钟,用dataset大概是要4秒 (早期的测试)

今天用msbuild 在 june 2007 ctp的测试,

var list=nmis.QuotationLines.ToList() ;

居然不到 2秒, 然后用直接 返回DataTable作比较,这次分别查询20次的累计值

linq to sql : 36583   还用console输出日志

datatable : 63738

以上数据的数字大小没有意义,仅两者的比较有意义, 是不是数据量越小linq to sql 的性能就不太容易表现呢 ?(依据我早期的测试),接下来 我又测试了6000多条 的报价单记录. 在这次测试中,我关闭了linq to sql 的log输出,并 用 具体的字段代替dattable测试查询中的*

liqn to sql : 2850

datatable: 3219

结论是不是很明显了 june ctp 版本的性能提升了

当然,如果现在要作出 linq to sql  性能好于 datatable(dataset) 的结论现在还是有些武断,它需要更多的测试以及不同的应用场景,希望大家也能在自己的环境中测试以下.

btw:

1. 项目是手工创建,用msbuild编译的,因为目前没有适合这个版本的vs .net ,编译为debug版本

2. 报价单/报价单_明细的数据来自实际的业务系统, 报价单有20个字段,共计6772条,报价单_明细有 25个字段,76606条记录

3. 测试方式很简单,linq to sql 简单用ToList返回,datatable测试简单的使用select ... from ...查询

[2007-07-21 08:20:33 | Author:jiangjianxiao ] [] 1 comments

Total 91 Display 16 of 20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Powered by Google App Engine