微软轻量级“代码生成器”—Repository Factory使用(上)

概述

Repository Factory是微软模式与实践小组发布的一个开发指南包,它把之前的Web Service Software Factory(WSSF)集成的Data Access Guidance Package分离出来,形成了一个单独的开发指南包。引用Johnny Halife的话说:“它不是一个对象-关系映射(Object-Relational Mapping,ORM)工具,它的目的是作为一个轻量级的代码生成器,以自动化完成绝大部分生成领域模型对象,并将之持久化到数据库的任务代码。”本文为微软轻量级“代码生成器”—Repository Factory使用上篇。

Johnny指出了Repository Factory的改进之处:

1.开发包被移植到GAT/GAX上。

2.对WSSF的依赖全部移除,因此Repository Factory现在是一个完全独立的指南开发包。

3.之前由开发包生成并且包含多个基类的通用代码,现在被打包成为一个独立的DLL,并由Repository Factory项目引用。

4.生成了一个通用基本接口,来支持IOC模式。

5.除通用基本接口外,还生成了一个Factory类,并可以在项目配置文件中进行配置。因此,Repository Factory的实现方式可以通过修改配置文件切换。

6.为自定义存储操作的方便,加入了从实体字段到存储过程参数的自动映射。

7.数据库名称和配置从生成的Repository移植到了Repository<T>基类,连接字符串定义在配置文件中。

8.Repository方案的设置(操作和映射)现在可以保存起来以供重用。

下载安装

可以到RepositoryFactory官方主页上下载最新版本:http://www.codeplex.com/RepositoryFactory

注意安装之前请确保安装:

1.Guidance Automation Extensions

2.Guidance Automation Toolkit

启用RepositoryFactory

Step1:在Visual Studio 2005工具菜单中,选择Guidance Package Manager,可以打开指导包管理器:

TerryLee_RF_001

Step2:选择Repository Factory

TerryLee_RF_002

Step3:同时还需要在项目上右键菜单中,选择Specify project responsibility

TerryLee_RF_005

Step4:分别选择Business Entities Project、Data Access Project、Host Project。

TerryLee_RF_006

添加数据库连接

Step1:接下来需要添加数据库连接

TerryLee_RF_003

Step2:输入数据库连接串的名称:

TerryLee_RF_004

创建连接完成后,将会在配置文件添加代码:

<connectionStrings>
<add name="RFConnectionString" connectionString="Data Source=Esint-lhj\Sql2005;Initial Catalog=AdventureWorksDW;Persist Security Info=True;User ID=sa;Password="
providerName="System.Data.SqlClient" />
</connectionStrings>

创建实体类

用Repository Factory可以很方便的通过数据库架构,生成业务实体的代码。

Step1:创建业务实体

TerryLee_RF_007

Step2:选择数据库连接字符串

TerryLee_RF_008

Step3:选择数据表、视图和字段

TerryLee_RF_009

Step4:设置实体的属性了,可以设置业务实体的名称,默认的是表名;设置业务实体的属性名和该属性是否为只读属性

TerryLee_RF_010

点击完成后,会生成业务实体的代码,并且为局部类型,这样便于用户在该业务实体上添加自己的一些操作,示例代码如下:

public partial class DimGeography
{
public DimGeography()
{
}
public DimGeography(System.String city, System.String countryRegionCode, System.String englishCountryRegionName, 
System.String frenchCountryRegionName, System.Int32 geographyKey, System.String postalCode, 
Nullable<System.Int32> salesTerritoryKey, System.String spanishCountryRegionName, System.String stateProvinceCode,
 System.String stateProvinceName)
{
this.cityField = city;
this.countryRegionCodeField = countryRegionCode;
this.englishCountryRegionNameField = englishCountryRegionName;
this.frenchCountryRegionNameField = frenchCountryRegionName;
this.geographyKeyField = geographyKey;
this.postalCodeField = postalCode;
this.salesTerritoryKeyField = salesTerritoryKey;
this.spanishCountryRegionNameField = spanishCountryRegionName;
this.stateProvinceCodeField = stateProvinceCode;
this.stateProvinceNameField = stateProvinceName;
}
private System.String cityField;
public System.String City
{
get { return this.cityField; }
set { this.cityField = value; }
}
private System.String countryRegionCodeField;
public System.String CountryRegionCode
{
get { return this.countryRegionCodeField; }
set { this.countryRegionCodeField = value; }
}
private System.String englishCountryRegionNameField;
public System.String EnglishCountryRegionName
{
get { return this.englishCountryRegionNameField; }
set { this.englishCountryRegionNameField = value; }
}
private System.String frenchCountryRegionNameField;
public System.String FrenchCountryRegionName
{
get { return this.frenchCountryRegionNameField; }
set { this.frenchCountryRegionNameField = value; }
}
private System.Int32 geographyKeyField;
public System.Int32 GeographyKey
{
get { return this.geographyKeyField; }
set { this.geographyKeyField = value; }
}
private System.String postalCodeField;
public System.String PostalCode
{
get { return this.postalCodeField; }
set { this.postalCodeField = value; }
}
private Nullable<System.Int32> salesTerritoryKeyField;
public Nullable<System.Int32> SalesTerritoryKey
{
get { return this.salesTerritoryKeyField; }
set { this.salesTerritoryKeyField = value; }
}
private System.String spanishCountryRegionNameField;
public System.String SpanishCountryRegionName
{
get { return this.spanishCountryRegionNameField; }
set { this.spanishCountryRegionNameField = value; }
}
private System.String stateProvinceCodeField;
public System.String StateProvinceCode
{
get { return this.stateProvinceCodeField; }
set { this.stateProvinceCodeField = value; }
}
private System.String stateProvinceNameField;
public System.String StateProvinceName
{
get { return this.stateProvinceNameField; }
set { this.stateProvinceNameField = value; }
}
}

创建CRUD的存储过程

利用Repository Factory可以很方便的生成针对数据表的CRUD存储过程,可以生成Insert、Update、Delete、GetAll、GetOne、GetMany六种类型的存储过程。

Step1:选择Create CRUD Stored Procedures菜单

TerryLee_RF_011

Step2:仍然是选择连接

TerryLee_RF_012

Step3:选择要生成存储过程的数据表

TerryLee_RF_013

Step4:设置是否生成上面所说的六种存储过程以及存储过程的名称

TerryLee_RF_014

Step5:设置存储过程的输出文件

TerryLee_RF_015

生成的存储过程部分代码:

----------------------------------------------------------------
-- [dbo].[DimGeography] Table
--
IF NOT EXISTS (SELECT NAME FROM sys.objects WHERE TYPE = 'P' AND NAME = 'InsertDimGeography')
BEGIN
EXEC('CREATE PROCEDURE [dbo].[InsertDimGeography] AS RETURN')
END
GO
ALTER PROCEDURE [dbo].[InsertDimGeography]
@city nvarchar(30) = NULL,
@countryRegionCode nvarchar(3) = NULL,
@englishCountryRegionName nvarchar(50) = NULL,
@frenchCountryRegionName nvarchar(50) = NULL,
@geographyKey int OUT,
@postalCode nvarchar(15) = NULL,
@salesTerritoryKey int,
@spanishCountryRegionName nvarchar(50) = NULL,
@stateProvinceCode nvarchar(3) = NULL,
@stateProvinceName nvarchar(50) = NULL
AS
BEGIN
SET NOCOUNT ON
BEGIN TRY
INSERT INTO [dbo].[DimGeography] ([City], [CountryRegionCode],
[EnglishCountryRegionName], [FrenchCountryRegionName], [PostalCode],
[SalesTerritoryKey], [SpanishCountryRegionName], [StateProvinceCode], [StateProvinceName])
VALUES (@city, @countryRegionCode, @englishCountryRegionName,
@frenchCountryRegionName, @postalCode, @salesTerritoryKey,
@spanishCountryRegionName, @stateProvinceCode, @stateProvinceName)
SET @geographyKey = SCOPE_IDENTITY()
END TRY
BEGIN CATCH
EXEC RethrowError;
END CATCH
SET NOCOUNT OFF
END
GO

结束语

使用Repository Factory生成业务实体和存储过程,就介绍到这里,限于篇幅,分成了上下两篇,其他内容放在微软轻量级“代码生成器”—Repository Factory使用(下)。
参考:微软轻量级“代码生成器”—Repository Factory使用(下)
作者:TerryLee
出处:http://terrylee.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted @ 2007-11-29 21:23 TerryLee 阅读(9493) 评论(40) 编辑 收藏

 回复 引用 查看   
#1楼[楼主] 2007-11-29 21:29 TerryLee      
WCSF先停一下,写篇Repository Factory:)
 回复 引用 查看   
#2楼[楼主] 2007-11-29 21:32 TerryLee      
@罗战克
:)

 回复 引用 查看   
#3楼[楼主] 2007-11-29 21:32 TerryLee      
郁闷,代码怎么又左对齐了啊-_-
 回复 引用 查看   
#4楼 2007-11-29 22:46 Jeffrey Zhao      
--引用--------------------------------------------------
TerryLee: 郁闷,代码怎么又左对齐了啊-_-
--------------------------------------------------------
估计你用了博客园的某个编辑器打开过了,它会合并连续的空格——殊不知你用了<pre />来包装,呵呵。所以我其实一般在播客园就用普通的文本编辑器。

 回复 引用 查看   
#5楼[楼主] 2007-11-29 22:53 TerryLee      
@Jeffrey Zhao
是啊,我打开编辑了就成这样了,唉

//我也要改用普通的文本编辑器

 回复 引用 查看   
#6楼 2007-11-29 23:31 雨过流痕      
李天平的代码生成器也很好呀! ^_^
 回复 引用 查看   
#7楼[楼主] 2007-11-29 23:34 TerryLee      
@雨过流痕
很少在项目中能用到,没有基于模板,很难自己去定制生成的代码

 回复 引用   
#8楼 2007-11-30 01:23 工作中ing[未注册用户]
可以不用CodeSmith了
 回复 引用 查看   
#9楼 2007-11-30 01:34 ξ箫音ξ      
TerryLee 写的不错.
 回复 引用 查看   
#10楼 2007-11-30 08:34 Wilensky      
很不错,支持TerryLee
 回复 引用 查看   
#11楼[楼主] 2007-11-30 08:41 TerryLee      
@工作中ing
CodeSmith收费,这个开源,呵呵

 回复 引用 查看   
#12楼[楼主] 2007-11-30 08:41 TerryLee      
@ξ箫音ξ
@Wilensky
谢谢:)

 回复 引用 查看   
#13楼 2007-11-30 08:42 Dove.Net      
很好的东西,喜欢“轻量级”
 回复 引用 查看   
#14楼 2007-11-30 08:42 overred      
支持。。。
 回复 引用 查看   
#15楼[楼主] 2007-11-30 09:01 TerryLee      
@Dove.Net
@overred
:)

 回复 引用   
#16楼 2007-11-30 09:24 dikong[未注册用户]
6.为自定义存储操作的方便,加入了从实体字段到存储过程参数的自动映射。
这条最好用了

 回复 引用 查看   
#17楼 2007-11-30 10:01 预备役中尉      
这个和我们研发部开发的一个差不多.只是我们的目前不提供存储过程.IOC等功能.根据使用反馈逐步完善中.
http://www.cnblogs.com/jiangshaofen/archive/2007/06/29/799643.html

 回复 引用 查看   
#18楼 2007-11-30 11:12 要有好的心情      
CodeSmith收费: CodeSmith2.6是免费的,我一直自己写代码生成的模板,定制起来方便。
 回复 引用 查看   
#19楼 2007-11-30 11:13 lodestar      
不错
 回复 引用 查看   
#20楼 2007-11-30 19:50 Enzo      
不错 第一手信息
看来,微软也在实施开源计划

 回复 引用 查看   
#21楼 2007-12-02 16:19 Osamede      
安装实验中 :)
 回复 引用   
#22楼 2007-12-02 22:00 小不点11[未注册用户]
遇到些问题,,生成Entity/存储过程/及Data Class后,在WebSite层,怎么调用??????

是否需要在WebSite层,引用Microsoft.Practices.Repository.dll的引用..
如果是IoC,那么是否还要增加对Business Entity层和Data层的项目引用?

在使用时,WebSite都需要添加哪些引用???

 回复 引用 查看   
#23楼[楼主] 2007-12-03 08:44 TerryLee      
@小不点11
具体如何使用,请参考
微软轻量级“代码生成器”—Repository Factory使用(下)

 回复 引用   
#24楼 2007-12-03 10:18 小不点11[未注册用户]
微软轻量级“代码生成器”—Repository Factory使用(下) 我已经看过了,可是里面并没有指出各项目之间引用关系,WebSite层对Repository Factory的引用.. 有多个Repository Factory.dll文件,差异很大,正确准确的引用过程,麻烦楼主描述下吧... 我也在查相关的资料.

我在用的时候遇到很多问题,各层代码已经生成好,但一运行就报很多错误,有时是空引用错误


 回复 引用   
#25楼 2007-12-03 10:20 小不点11[未注册用户]
不要意思把你这里帖的很乱,,可是我还没有解决这个问题...
QQ:99519, MSN:littledot@qq.com
能在线联系一下吗,加快解决的速度.

---------------------------------------------
未将对象引用设置到对象的实例。
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。

异常详细信息: System.NullReferenceException: 未将对象引用设置到对象的实例。

源错误:


行 24: }
行 25:
行 26: public Tab_AgentRepository()
行 27: : base()
行 28: {


 回复 引用   
#26楼 2007-12-06 16:52 A.Z|[未注册用户]
mark
 回复 引用   
#27楼 2008-03-06 14:52 FLYabroad[未注册用户]
精彩
 回复 引用   
#28楼 2008-03-31 01:14 gandancing[未注册用户]
如果在Repository下有这一个用于分页的函数:public List<Academic_team> Academic_team_GetPaged(string where, string oderby, int pageIndex, int pageCount)应该怎么写ISelectionFactory呢?
 回复 引用 查看   
#29楼 2008-09-08 08:14 赵岩      
建议楼主以后加连接的时候 在新的窗口打开
要不很容易重复切换
呵呵

 回复 引用 查看   
#30楼[楼主] 2008-09-10 23:47 TerryLee      
@赵岩
博客园的习惯是在原窗口打开,我以为大家都习惯这种方式了呢,其实可以通过按住Shift键在新窗口中打开:)

 回复 引用   
#31楼 2008-09-27 15:27 soldierluo[未注册用户]
生成的存储过程有很多错误,不能直接使用,需要修改,请问问题出现在哪里?

服务器: 消息 195,级别 15,状态 10,过程 RethrowError,行 4
'ERROR_NUMBER' 不是可以识别的 函数名。
服务器: 消息 195,级别 15,状态 1,过程 RethrowError,行 19
'ERROR_NUMBER' 不是可以识别的 函数名。
服务器: 消息 195,级别 15,状态 1,过程 RethrowError,行 30
'ERROR_MESSAGE' 不是可以识别的 函数名。
服务器: 消息 170,级别 15,状态 1,过程 InsertluoUsers,行 11

 回复 引用   
#32楼 2008-09-28 10:00 soldierluo[未注册用户]
可以生成代码却无法使用,总是提示错误,但是用ASMX来生成的代码却又可以用,这是为什么啊?谢谢
 回复 引用   
#33楼 2008-09-28 12:16 soldierluo[未注册用户]
您好!!!
请问如何结合WCSF和Repository Factory来使用,因为在向init.cs中moduleServices.AddNew(即添加服务模块时)是不可行的,因为生成的...Repository.cs还继承了Repository<...>,所以我们该如何来注册服务呢?
谢谢

 回复 引用 查看   
#34楼 2008-11-03 11:31 尘土飞扬      
還喜歡這外東西,為什么沒有真正實用的東西呢?
 回复 引用 查看   
#35楼 2009-03-31 16:59 晴网      
我也写了一个呵呵 只是没有做成VS内置 因为我想支持多种数据库和生成其他语言的代码

http://www.cnblogs.com/jeremychin/archive/2009/03/24/1420818.html

 回复 引用 查看   
#36楼 2009-10-12 02:05 吴淑荣      
“参考:微软轻量级“代码生成器”—Repository Factory使用(下)”

文章底部这个超链接给错了哦。


 回复 引用 查看   
#37楼 2010-12-12 06:06 manimanihou      
soldierluo:生成的存储过程有很多错误,不能直接使用,需要修改,请问问题出现在哪里?
<br/>
<br/>服务器: 消息 195,级别 15,状态 10,过程 RethrowError,行 4
<br/>'ERROR_NUMBER' 不是可以识别的 函数名。
<br/>服务器: 消息 195,级别 15,状态 1,过程 RethrowError,行 19
<br/>'ERROR_NUMBER' 不是可以识别的 函数名。
<br/>服务器: 消息 195,级别 15,状态 1,过程 RethrowError,行 30
<br/>'ERROR_MESSAGE' 不是可以识别的 函数名。
<br/>服务器: 消息 170,级别 15,状态 1,过程 InsertluoUsers,行 11酱油何处有。。
northface outlet69snow boots for women96the northface outlet