更新自己,不要影响其他人

最近围绕着c++和C#的讨论越来越激烈,firelong努力着证明自己的观点,园子里一些大大们也在激烈的辩证着,作为小鸟的我,旁观,看看一笑而过吧。

其实无论哪种语言,肯定有它的优势和劣势,我们何必去争个你死我活呢?我承认firelong有些观点正确,但这些会影响我们吗?我相信有一定基础的程序员,都不会去在意,因为我们选择的不仅仅是语言,或许还有更多,如果单单靠某些人的一些观点,我们就改变了,那也太没立场了,变成墙头草了不是?

但我很喜欢看这种讨论,因为firelong把自己的观点,例子举了出来,而不是理论上的进行驳斥,这种文章看出来是作者用心实践过的,我们应该支持,对于那种没有实践,只是一再的崇拜或者诋毁的人,出来就是辱骂的,大家一起来鄙视下吧。

今天不是为了参与讨论,正好今天遇到了个问题(其实一直懒得解决),符合了标题,随便说说,说的难听了,大家见谅,笑笑而过吧。

问题其实很简单,更新静态变量的值,而这个值呢,又是从linq to sql中获取的,大概的结构如下:

    public class MyConfig
    {
        private static DataLoader s_loader;

        static MyConfig()
        {
            s_loader = new DataLoader();
        }

        public static List<Company> AllCompanies
        {
            get
            {
                return s_loader.GetAllCompanies();
            }
        }

        public static List<MyType> AllTypes
        {
            get
            {
                return s_loader.GetAllTypes();
            }
        }
    }

 

简单的一个获取配置信息的一个类(这是举例用的,实际使用中并不是这样)。

DataLoader 是与数据库相关的一个操作类,主要是通过linq to sql 来获取数据库中的信息。

代码:

public class DataLoader
    {
        public DataLoader()
        {
        }

        DataClasses1DataContext context = new DataClasses1DataContext();

        internal List<MyType> GetAllTypes()
        {
            
            return context.MyType.ToList();
        }

        internal List<Company> GetAllCompanies()
        {
            return context.Company.ToList();
        }
    }

代码丑了点,见谅见谅,主要的目的只有2个,获取所有类型和获取所有公司。

实际运用在了web项目中,又有另外一个后台专门来修改数据,这时候就出现了一个问题,默认情况下,linq to sql 会从缓存中获取数据。

操作步骤如下:循环读取MyType-》无论利用什么方法,修改数据库的MyType值-》再次读取。

因为用了命令行项目来实验的,那必须修改前和修改后都不能关闭命令行程序。以下简单的测试代码:

        static void Main(string[] args)
        {
            var key = String.Empty;
            while (key != "quit")
            {
                key = Console.ReadLine();
                MyConfig.AllTypes.ForEach(c => Console.WriteLine(c.Title));
                MyConfig.AllCompanies.ForEach(c => Console.WriteLine(c.Name));
            }

            Console.WriteLine("program to quit...");
            //Console.ReadLine();
        }

测试很简单,只要不输入quit,每次都会输出类型标题和公司名称。看下前后结果:

image (修改前读取的数据)

imageimage (利用Sql Manager Studio修改数据)

 image (修改后读取的数据)

 

看到了,这就是linq to sql 的缓存造成的结果,为了避免这个情况,我们可以使用以下方法:

1、把DataContext.ObjectTrackingEnabled属性设置为false

     因为linq to sql获取数据缓存的时候,先检索标识是否改变,如果未改变,则会用缓存中的数据。而ObjectTrackingEnabled设为false后,会关闭标识管理和变化跟踪,那样每次获取都会是最新的数据。(以下是重新测试结果,测试前数据恢复)

image    ----   image

目的是达到了,我们知道关闭ObjectTrackingEnabled属性,是一个好的提升性能的方式,但有时候也会造成一定的麻烦,比如更新、比如我要获取一对多,多对多的对象时。(其实是自己一开始没注意到,等改了以后发现项目中。。。。已经惨不忍睹了,绿一下自己)。

2、DataContext.Refresh方法。

      使用指定方法刷新实体对象(摘自msdn)。使用它以后,我能更新自己,而不影响其他人了。Refresh的方法,大家可以看msdn,我就写下代码吧,代码只修改了获取类型的方法。

internal List<MyType> GetAllTypes()
        {
            var types = context.MyType.ToList();

            context.Refresh(RefreshMode.KeepChanges, types);

            return types;
        }

我们再测试下(数据恢复先,直接上结果了):

image

实验成功,获取到了最新的MyType值,而公司的值则是修改前的,当然在程序下次运行的时候,就会变成最新的了。

3、重新实例化DataContext。(不说了)

 

以上东东纯属乱写,只是自己遇到的一个问题,可能写的不好,大家也不要拼命砸砖哦。

 

再说说最近的激辩吧,大家也不要辩论什么了,只要做好自己,努力提高自己就好,我们在实际应用中,会遇到许许多多的项目,每个项目的开始,都会商量好用什么语言来写,什么框架来建,不要为了哪个语言好哪个语言不好去争个不休,每个项目都会有不同的需求,用最适合的而不是用最好的,那就行了。

-----------------------------------------------------
      网名:James.Ying(玄天尊)

      MSN:x_inday@msn.com

      经验:5年电子商务网站开发

      目标:电子商务平民化。

-----------------------------------------------------

posted @ 2010-06-25 15:01 James.Ying 阅读(2361) 评论(11) 编辑 收藏

 回复 引用 查看   
#1楼 2010-06-25 15:24 Ray Gu      
其实,在我看来,不管哪个语言,能产生盈利,价值,就可以了,何必去争语言好坏,技术人员总是避不开钻牛角尖,客户和销售人员关心的不是用什么语言,而是能为他产生多少价值
 回复 引用 查看   
#2楼 2010-06-25 15:40 伤心的地瓜      
楼主是没有搞明白firelong写这些的目的是什么。
5年开发经验还称自己为小鸟,杯具。

 回复 引用 查看   
#3楼 2010-06-25 16:15 gihelo      
呵呵,本来不想说撒滴,只是单纯的进来逛逛。不过赶巧的事是,我最近刚好做了一个和博主一样游轮站。(http://www.3xyou.com/)嘿嘿发个地址,希望下面的人别误会是广告,只是很单纯想交流一下
 回复 引用 查看   
#4楼 2010-06-25 16:32 dongzz      
我的vs背景配色也是黑色,觉得挺酷的。
 回复 引用 查看   
#5楼 2010-06-25 17:04 舞千愁      
眼睛看得不舒服啊,黑色的。。还是蓝色的好点!
 回复 引用 查看   
#6楼 2010-06-25 18:32 a-peng      
怪怪的测试
1. datacontext被当成static来用
2. 你从数据库直接修改数据,而真实场景下你会submitchange datacontext

 回复 引用 查看   
#7楼 2010-06-25 20:27 户籍民警      
你也是做旅游电子商务的,是那个站的?
 回复 引用 查看   
#8楼 2010-06-25 21:06 双鱼座      
@伤心的地瓜
称小鸟合适不合适我就不下结论了。我不说写代码的人,我只说说我对代码的看法:
1.MyConfig只是DataLoader的包装,这是一个典型的Singleton模式,是不需要占用两个类的。
public class DataLoader {
private DataClasses1DataContext context;
private DataLoader() {
context = new DataClasses1DataContext();
}
public List<MyType> GetAllTypes() {
return context.MyType.ToList();
}
public List<Company> GetAllCompanies() {
return context.Company.ToList();
}
public static readonly DataLoader MyConfig = new DataLader();
}
当然,这样的代码不支持延迟加载,这个是缺陷,不过他以前的代码也没有实现延迟加载的。
2.DataContext是一个实现了IDisposable接口的类,不可以象上面的代码那样随随便便就创建一个实例然后不再管他。这个接口专门用来处理GC管不了的事情。不知道作者打算安排什么时候执行它的Dispose方法?
3.这个对象实例化并抓出所有的数据后,没人通知它数据被修改了,它如何知道要重新抓取?如果把DataContext.ObjectTrackingEnabled永远设置成false那还不如直接每次调用数据抓取方法来得方便。正确的做法是自己实现一个离线数据管理(当然不反对你用企业库的缓存管理来做),当需要更新数据时再通知离线数据失效,下次自动会去抓取最新的数据。
坦白说如果我的手下写这样代码来给我看我会非常伤心。如果他已经写了五年代码我就不必伤心了,立刻让他走人。

 回复 引用 查看   
#9楼[楼主] 2010-06-26 14:23 James.Ying      
@双鱼座
代码是用来做演示用的,因为我觉得这些代码已经足够说明我的问题了。

坦白说,我演示的代码好像不需要去演示IDisposable接口吧。还有。。。阁下的代码,貌似也没有高明之处- -!


 回复 引用 查看   
#10楼 2010-06-26 14:40 pqmagic      
支持楼主前半部分的观点,但貌似贴的代码,跟firelong的语言之争没有任何关系..
根据微软官方文档建议,Linq中的DataContext确实不适合用静态,尽量在一个短的周期内用外就释放。静态的datacontext不仅仅是取到的数据没有更新,在多线程环境下,还会引发很多致命的错误。。

 回复 引用 查看   
#11楼 2010-06-26 21:30 hb_cattle      
引用Ray Gu:其实,在我看来,不管哪个语言,能产生盈利,价值,就可以了,何必去争语言好坏,技术人员总是避不开钻牛角尖,客户和销售人员关心的不是用什么语言,而是能为他产生多少价值