数据库方面执行以下命令:
CREATE DATABASE Test;
go
USE Test;
CREATE TABLE A1([ID] int IDENTITY PRIMARY KEY NOT NULL,[Name] varchar(50) NOT NULL);
go
INSERT INTO A1([name])VALUES('test');
SELECT * FROM A1;
数据库中有以下一条数据:然后用CodeSmith5.2按nettiers模版生成项目,打开Test.sln,新加一个ConsoleApplication的控制台程序ConsoleDemo,如下:
把WebSite的Web.config部分内容copy致ConsoleDemo的App.config,然后在Program.cs中写入如下代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Test.Data;
using Test.Entities;
namespace ConsoleDemo
{
class Program
{
static void Main(string[] args)
{
A1 a1 = DataRepository.A1Provider.GetById(1);
Console.WriteLine(string.Format("A1.Name:{0}",a1.Name));
a1.Name = "HAHAHA";
Console.WriteLine(string.Format("A1.Name已改为:{0}",a1.Name));
A1 a2 = DataRepository.A1Provider.GetById(1);
Console.WriteLine(string.Format("A1.Name:{0}", a1.Name));
Console.Read();
}
}
}
按F5运行,将会看到如下错误:
这时会发现在取a2的时候,a1的值却发生了变化,我们可以假设CodeSmith的实现机理a1和a2其实就是一个成员实例,所以会是一样的值,但在代码上,这样有时会出问题的,毕竟a1和a2没任何关系。
框架就像一把双刃剑,一方面方便了我们,另一方面又让我们不得不花时间去研究……
------------------------------------第二天的研究------------------------------------
我们跟进调试,发现使用了缓存,有实体工厂(EntityFactories),很遗憾,和这个没关系。
然后我们发现EntityManager.cs中有实体跟踪(EntityTracking),注释写着:跟踪一个实体,直到它被更新或失效。嗯,好像跟这个有关了。
然后我们查询相关资料,终于在这里找到了一个门:
我们看对EntityLocator的解释:
EntityLocator是在微软企业库ObjectBuilder框架Locator类上假设的,locator用于创建一个弱引用的对象仓库,这样如果你的系统要处理大量实体对象的话,很多要使用的实体对象就都是相同的数据,所有的引用我们就返回相同的对象直到这个实体发生更新或被删除。有了这个功能,再使用乐观并发,在你的数据表上设置一个时间戳,最终你节省了不少内存消耗。可能有些人不知道,弱引用意味着哪些没有再被引用的对象始终会被垃圾回收器迅速的回收。
这个功能可以在app/web.config中的enableEntityTracking="true/false"配置是否开启使用。
在app/web.config中这样:
好吧……就是这样。