2008年5月14日

ADO.NET Entity Framework beta 3 和Linq to SQL 在缓存处理上的不同

Linq to SQL内置缓存功能,简单的说,当你查询了一次某个键的数据后,再次查询时linq to SQL的引擎不再向数据库发送SQL,例如:

            //下面是使用LinQ to SQL 的例子,context2是派生自System.Data.Linq.DataContext的实例
            ErpLinQContextDataContext context2 = new ErpLinQContextDataContext();
            
//SQLServer事件探查器拦截到SQL语句的执行
            
//exec sp_executesql N'SELECT TOP 1 [t0].[emp_id], [t0].[fname], [t0].[minit], [t0].[lname], 
            
//                         [t0].[job_id], [t0].[job_lvl], [t0].[pub_id], [t0].[hire_date]
            
//FROM [dbo].[employee] AS [t0]
            
//WHERE [t0].[emp_id] = @p0', N'@p0 varchar(9)', @p0 = 'PMA42628M'
            employee p3 = context2.employees.First<employee>(p => p.emp_id == "PMA42628M");
            
//当我再次执行相同的查询时,LinQ to SQL 不再向SQL Server发送查询了。
            employee p4 = context2.employees.First<employee>(p => p.emp_id == "PMA42628M");

而且,这两个实例是同一个实例

            //返回的对象是同一个实例
            bool b2 = object.ReferenceEquals(p3, p4); //=true;
            p3.lname = "New Last Name";
            
bool b4 = (p4.lname == "New Last Name");  //=true;

当然,如果你使用不同的Context实例查询时,缓存功能将实效。

好,让我们再看看ADO.NET Entity Framework beta 3:

            //pubsEntites是 ADO.NET Entity Framework 的System.Data.Objects.ObjectContext派生对象
            pubsEntities context = new pubsEntities();

            
//下面语句执行时,SQLServer事件探查器拦截到SQL的执行
            
//SELECT TOP 1 [Extent1].[emp_id] AS [emp_id], [Extent1].[fname] AS [fname], [Extent1].[lname] AS [lname], 
            
//             [Extent1].[hire_date] AS [hire_date], [Extent1].[job_id] AS [job_id], [Extent1].[pub_id] AS [pub_id]
            
//FROM [dbo].[employee] AS [Extent1]
            
//WHERE N'PMA42628M' = [Extent1].[emp_id]
            Employee p1 = context.EmployeeSet.First<Employee>(p => p.EmployeeId == "PMA42628M");

            
//SQLServer事件探查器 发现SQL再次被执行
            Employee p2 = context.EmployeeSet.First<Employee>(p => p.EmployeeId == "PMA42628M");
            
//测试发现,虽然ADO.NET Entity Framework执行了两次SQL,但是他们却返回了完全相同的实例
            bool b1 = object.ReferenceEquals(p1, p2); // = true;

测试的结果是,ADO.NET Entity Framework(以下简称AEF)没有使用缓存,而是再次执行SQL,但是你要注意:两次查询的实例竟然是同一个。
从Context功能上看,他肯定持有上次查询的结果,他没有使用缓存,我只能认为可能AEF被设计成三层应用,那么他很担心其他的进程将数据改了,所以不使用缓存,当发现数据并没有改后,还是使用原先的实例,这个想法对吗?
我们再看看另外一个代码:
            //如果使用不同的上下文更新的数据,
            pubsEntities context4 = new pubsEntities();
            Employee p10 
= context4.EmployeeSet.First<Employee>(p => p.EmployeeId == "PMA42628M");
            p10.LastName 
= "Context4 changed data";
            context4.SaveChanges();

            
//旧的context再次查询时。
            Employee p11 = context.EmployeeSet.First<Employee>(p => p.EmployeeId == "PMA42628M");
            b1 
= object.ReferenceEquals(p1, p11); //= true   why??
            b1 = (p11.LastName == "Context4 changed data"); //= false  p11.LastName = "New Last Name"
难以置信,AEF重新执行了SQL,但是置新的更改而不闻,仍然返回旧的数据。这个算是Bug吗?

我不知道哪位达人能够解释这个问题?当然,这个问题我也询问了MS,他们的技术人员还未做出满意的答复。
posted @ 2008-05-14 13:54 编写人生 阅读(865) | 评论 (2)编辑

向灾区捐款,自我纪念一下

 我不是那种“做好事不留姓名” 的那种, 纪念一下。
但还是少些这种捐款好,我的意思是希望天下太平。都不用捐款才是最好。
希望中国少些灾难,军队能够提高能力,设备先进些。
posted @ 2008-05-14 11:33 编写人生 阅读(9) | 评论 (0)编辑
2008年5月4日

关于购买日本车所联想的两个故事

    我们知道,网上很多人是很鄙视 买日本车的人 的。我不想骂人,我想讲两个事情。
    第一个就是:清朝时林则徐提出的“师夷长技以制夷”,我想用在现在的中国汽车一样正确。
    第二个是将日本侵略中国时,当时在中国有很多的诸如“翻译官”这样的职业,在当时看来,这样的职业工资是很高的,而且人家又不直接杀人,所以其实当时很多的中国人是给日本人打工的。现在套用中国汽车业,大概也能说明一些,因为日本车比起中国自主品牌来说,质量的确好很多,而且相对德国车,他的确又便宜很多。所以很多中国人还是禁不住诱惑,觉得买日本人的东西很合算。
    我坦诚说我对日本的态度:
    一,日本人很多方面不错,我们应该“师夷长技”,比如他们严谨的工作作风和科技等,
    二、日本到现在仍然对历史的错误不予悔改,这是我最不能容忍的;
    三、日本毕竟人多地少,又是个地震频发的岛国,套用他们的话“凭什么我们这么优秀的人要住在这个岛国,而那些愚昧的中国人可以享受那么好的土地”,所以只要是正常人的思维,日本人终究有一天,还是要再次侵略中国的。
    所以,我尽我最大能力不购买日本产品,并劝导朋友和同事不购买日本产品。
posted @ 2008-05-04 12:49 编写人生 阅读(21) | 评论 (0)编辑
2008年4月29日

MarshalByRefObject 的性能损失

以前看过文章说MarshalByRefObject 会造成性能的损失,我比较相信自己,所以亲自测试了一下,下面是代码:

测试代码

测试的结果是:
 B 花费时间:55
A MarshalByRefObject 花费时间:957
A MarshalByRefObject 花费时间:972
B 花费时间:56
                  

总结:像这样在本地环境下,性能仍然损失了近17.4倍。当然,此17被不能简单的理解为你的应用就慢了17倍,这里仅表示发起调用损失了17倍。
posted @ 2008-04-29 15:20 编写人生 阅读(93) | 评论 (0)编辑
2008年4月28日

相信自己,我能2 — ORM 工具的插入性能比较

请先参考《相信自己,我能》 关于读取性能的测试

今天对插入的性能做了比较,和我预期的一样,Torridity的性能和其他的产品基本打平手,而Entity Framework一样是糟糕的成绩。
为什么认为会打个平手呢?因为插入1万比记录,意味这连续发送1万次SQL,在没有提别糟糕的程序下,基本上SQL语句的执行花去了几乎大部分的时间,程序本身的优化所得到的提升几乎微乎其微。
下面是测试结果:

再次失望ADO Entity Framwork的性能,太糟糕了

posted @ 2008-04-28 18:10 编写人生 阅读(111) | 评论 (0)编辑
2008年4月25日

MS ADO.NET Entity Framework beta 3 探秘

关于元数据结构
自动创建的代码包含一个派生自ObjectContext的对象,他有点像一个Workspace,主要包含连接、元数据和状态管理等;

ObjectContext包含一个MetadataWorkspace属性,记录了所有的元数据信息,有几种类型:
C  Space: 很全,包括数据类型(例如Byte)、函数(例如Max)、实体类型(例如Order);
CS Space:null?没有吗
OC Space:纯数据类型,一般13个;
S  Space:包括数据类型和实体类型。
你可以像下面这样的代码获取元数据
EntityType c2 = c.MetadataWorkspace.GetItem<EntityType>("DcmsCore2_TestModel.Customer", System.Data.Metadata.Edm.DataSpace.CSpace);

枚举出一个元数据对象,怎么知道是描述什么的呢?BuildtInTypeKind属性可以告诉你,常见的有:
PrimitiveType    : 原生数据类型,例如描述string的
EntityType       :实体类型,一般是ClrEntityType的实例,例如描述order
MetadataProperty : 属性,例如描述Order的属性OrderId;
Facet            :特性,用来描述是否允许null,或缺省值之类的东西,有点像CLR里面的Attribute

posted @ 2008-04-25 15:13 编写人生 阅读(25) | 评论 (0)编辑

《比亚迪员工的心声》一文留贴

看见一文章《比亚迪员工的心声》,原文是:
首先声明一下:本人是比亚迪公司的一名工程师,看到这么多的争议,不管是好的还是不好的评论,至少证明大家还是关注这个公司的汽车。提建议是好的,但是别带上个人的主观情趣,说句实在话我也不知道公司的车到底好不好,但是我知道的是我们确实一直在改善,也许你们觉的这个车这里缝隙大,那里配合不好,那里又怎么差的。那我想问你们一句:你们的标准是什么呢?如果你拿宝马奔驰来做标准那我劝你暂时还是不要来发表了,因为我们还没有达到那种高度,我们是民营企业,要养活十几万人,换句话说我们要生存。从开始的F3到现在的F6如果说没有改进的话我把头给你们当球踢,但是改进要一个过程,不是你今天说要改明天就可以改好了,可以说理论的东西我们可以设计到一丝不差,但实际加工出来就不是你想的那样了。每一个改进都要经过N多的程序。举个很简单的列子吧:如果要改进一个地方的配合间隙,是不是要修改其中一边的尺寸,是不是涉及到模具的尺寸,这个东西是钢铁做的,不是泥巴你捏一下它就变长了。光是这样的模具拆下来都要很长的时间更不要说加工了。所以要理性的看待问题。就像很多的F3车主说的一样,现在出来的F3比以前的工艺好多了。确实如此,
因为我们一直在努力。我们不止做汽车,我们做电池,做IT,我们的IT已经做到了0.005MM的公差。所以我们很有信心把汽车这一块做好。
当然更希望广大车友提意见到我们公司。

==============================================
我的看法是:
好热闹啊,我也插一句,我就不愤青了
说到底,商家要赢,拼到底就是看谁能够持久的提供高性价比的产品和服务,
例如,在6万这个价位上,我造的汽车比别的汽车看起来就是漂亮些,质量就是好些,就会大把有人买。
人是贪心的,很多客户买了10元的东西也会要求送货上门,为什么不可以呢?盒饭就可以,但是如果你300元买洗衣机,还要送货上面就没有人愿意了。
如果这个时候有厂家说,300元我可以卖给你洗衣机,但不提供送货上门,我敢向上帝保证:还是有人要求送货上门的,因为人是贪婪的。你可以想象,如果这个厂家坚持不送货上门,我相信结果是:客户一边骂,一边在买,然后心中窃喜,骂完了之后又打电话叫上他的大哥小弟赶快来抢。
好,我们继续,很不幸,这个厂家刚开始买的300元的洗衣机质量还是不错的(所谓质量不错,是指通常理解的不经常坏),后来觉得没有利润就开始偷工减料,质量不行了,但商家凭良心说,这个洗衣机只有10元利润了,但是这个时候客户会买单吗?不会,在这个例子中客户是不会的,为什么?因为客户愿意掏更多的钱买个质量好的洗衣机。这个钱客户觉得他掏的起掏的值,就像你可以理解一个普通的白领不会买巷子角落的1毛钱的烧饼,即使天地良心,这个烧饼成本就已经是1毛了。
我们再假设,人的智慧太厉害了,很多的厂家经过努力,他们的洗衣机也卖到300了,质量一样的好,那么这个厂家继续说,我不送货上门,还有人了他吗?还是300,还是不送货上门,为什么结果不一样了。

总之,在保证基本利润的基础上,给客户最大化的利益才是商家持久发展之道。

大家也可以参考 施乐和佳能 关于复印机的案例。
posted @ 2008-04-25 10:17 编写人生 阅读(28) | 评论 (0)编辑
2008年4月24日

网络负载平衡 值得记录的事情

这个事情应该是前几天的事情了,由于一直比较忙,所以没有写下来。
我们利用微软的网络负载平衡,假设了两台应用服务器,并在另外一台计算机部署了我们的会话服务器和SQL Server 2005服务器。
测试的结果是:
客户端面对的是一个IP地址,应用服务器将随机处理客户的请求;
有一个客户已经连接到服务器,这时我们关闭了其中一台服务器的电源(模拟服务器崩溃),我们看见客户端顺利的重定向到另外一台服务器,一起都非常平滑。

这次测试终于完成了我几年来一直追求的目标:负载平衡。他是值得纪念的事情。
posted @ 2008-04-24 14:28 编写人生 阅读(20) | 评论 (1)编辑

相信自己,我能

今天,是个值得纪念的日子,因为我编写的ORM(名为Torridity)工具经过性能测试,其读取性能全面压倒DataSet、LinQ和DataEntity Framework。

 

从截图中你可以看出,我们比DataSet快2倍,比LinQ快4倍,比Entity Framework beta 3快14倍。

测试采用读取1万笔记录,而且为公正起见,所有的计时开始前,都预先读取一笔其他的记录,保证不是连接缓冲池造成的误差。而且测试代码保证都是各自工具最佳的读取方式。

你可以下载附件中的测试程序,但非常的遗憾,Torridity属于公司的财产,所以我不能包含任何关于此部分的代码。要测试程序请:

  - 使用Visual Studio 2008打开项目;

  - 下载Entity Framework beata 3;

我将在随后的时间测试保存、插入和删除功能的性能。

LinQVsTorridity.rar 


请不要发表诸如以下的意见:都没有实际程序在那吹吧。
我想说的是,这个文章仅是为了纪念我的成果,证明自己的能力,以此纪念。
posted @ 2008-04-24 13:43 编写人生 阅读(55) | 评论 (1)编辑
2008年3月24日

差点买养老保险了!!保险和存款你算过吗?你一定要看的

老婆联系友邦保险的人,希望可以买些养老保险,因为我们都是外来打工人员,没有上海本地户口,也没有居住证(我们的文凭不行,只有高中),所以也不能享受四金。我们必须为我们的养老问题做准备。
他们给了我们两个方案,两种方案都是从28岁交到48岁(20年),55岁(再等7年)可以开始领钱。:
方案1 :
每年交5610(合计本金112200),你的收益是: 177000(领取20年的钱)+57511(55岁时一次性领取)+35697(65岁后一次性领取)=270208
注意此方案中177000是保证可以领取的,后面的钱属于投资性,不保证收益的。

方案2:
每年交6356(合计本金127120),你的收益是:1000*12月*20年=240000

好了,不管哪种方案,都能领取至少2倍的钱,1000元对于我们养老来说,温饱应该没有问题,而且每月500-600的支出也不是很大,所以欣然

签字,OK。

好了,等他们走后,我想起来如果我们存款会怎样呢?父母的老办法是不是更有效呢?我通过:

http://www.icbc.com.cn/calculator/calculator_per.jsp 详细计算了一下。
我是这样存款的:第一个5年我零存整取,5年到了之后我提取所有的钱包括利息,整存整取5年,当然我会继续零存整取5年,我的存款记录如

下:

以467.5(第一种方案每月平摊)月计算
5年后:30853.98(零存整取合计)
10年后:30853.98(零存整取合计)+39427.53(30853.98整存整取合计)=70281.51
15年后:30853.98(零存整取合计)+89810.98(70281.51整存整取合计)=120664.96
20年后:30853.98(零存整取合计)+154194.74(120664.96整存整取合计)=185048.72
25年后:236469.13(185048.72整存整取合计)
27年后:257495.97(236469.13两年整存整取合计)

天啊!老人的办法一点不老土,绝地比买保险合算,好处多多:
1、这种存款方法风险极小,不管是提款风险,还包括存款风险(你真的没有钱存款了也不会丢钱);
2、收益更佳,虽然表面上存款比第一种方案少一点点,但是保险公司没有保证这个是一定有的,但是明显比第二种方案还多;
3、55岁后你的钱在你手上,而保险的话钱在保险公司上,如果你愿意每月拿钱花的话,你可以每月拿1072.89,但是你要知道我没有算后20年的利息,所以你实际上可以自由的继续存款。我的方案是继续存款,但是我每月拿1500做生活费。

5年:现有257495.97,减去90000(1500*12*5)剩余167495.97,存5年整存整取,剩余214038.91;
10年后:214038.91 - 90000 = 124038.91,存5年整存整取,剩余158506.22;
15年后:158506.22-90000=68506.22,存5年整存整取,剩余87542.39;
20年后花光。 差2500多可忽略不计。


哈哈,存款比保险整整多了500,为什么不用这种办法呢???赶紧打电话给保险取消合同。

补充:
我当然知道通货膨胀的问题,我的意思是比保险合算,参加这样的保险他也没有说为你考虑通货膨胀啊!
有方法抵消通货膨胀吗?买房子?买黄金?买股票?稳妥的办法中都没有抵制通货膨胀的方法。
27年前,80元可以养活一个人一个月,现在1800元是基本吧。意味着20倍通货膨胀,那么我可以反过来算1500/20,那么相当于现在的75,可以买什么呢?我想的确不能养活一个人。就像现在81年的80元不能养活现在的一个人了。
我们永远不能算的过国家机器。我的计算仅代表:存款比商业养老保险合算
多元化投资是比较好的办法。

posted @ 2008-03-24 10:51 编写人生 阅读(360) | 评论 (13)编辑