查询模式
框架要求以一种统一的开发模式来编写实体仓库的查询方法,来兼顾本地应用、分布式应用程序的开发。不论在客户端,还是在服务端,都可以直接调用这种查询接口。这种开发模式如下:
[RepositoryQuery]
public virtual WarehouseList GetByCode(string warehouseCode)
{
var q = this.CreateLinqQuery();
q = q.Where(e => e.Code == warehouseCode);
return (WarehouseList)this.QueryData(q);
}
必须标记为虚方法。
这是因为框架需要对仓库生成代码,并对该方法进行拦截。
方法需要标记:[RepositoryQuery]。
不是所有的虚方法都会被拦截,所以需要显式标记来区分公有数据方法。
添加此标记后的方法拥有以下的功能:
1.判断是需要在本地、还是服务端来执行此方法。如果需要在服务端执行,则框架会转而调用 WCF 数据门户。(如果需要分布式调用,所有参数需要支持可序列化。)
2.根据方法的返回值,来确定底层查询时应该返回的类型(EntityList、Entity、int、LiteDataTable)。
3.查询完成后,调整查询结果的类型,与需要的类型一致。
返回值
方法的返回值只可以是以下几类,具体实体列表类型、具体的实体类型、int(查询数据条数)、LiteDataTable(轻量级数据表格类型)。
方法体
方法体中需要构造查询,并最终使用
QueryData()来查询数据。QueryData()方法会根据当前查询方法的返回值,而决定底层需要执行的查询的类型(查全部实体、查单个实体、查数据条数),并返回相应类型的数据。
四种查询示例
四种查询对应枚举 Rafy.Domain.RepositoryQueryType:
/// <summary>
/// 仓库返回数据的类型
/// </summary>
public enum RepositoryQueryType
{
/// <summary>
/// 查询实体列表
/// </summary>
List = 0,
/// <summary>
/// 查询单个实体
/// </summary>
First = 1,
/// <summary>
/// 查询数据条数统计
/// </summary>
Count = 2,
/// <summary>
/// 查询数据表格
/// </summary>
Table = 3
}
查询实体列表
返回具体实体列表类型。
[RepositoryQuery] public virtual WarehouseList GetByCode(string warehouseCode) { var q = this.CreateLinqQuery(); q = q.Where(e => e.Code == warehouseCode); return (WarehouseList)this.QueryData(q); }查询单个实体
返回具体实体类型。
查询实体个数的数据层实现中,与查询实体列表的实体层实现保持一致。如果查询出多条实体,则框架只会返回第一个实体。
[RepositoryQuery] public virtual Warehouse GetByName(string name) { var q = this.CreateLinqQuery(); q = q.Where(e => e.Name == name).OrderByDescending(e => e.CreateTime); return (Warehouse)this.QueryData(q); }查询实体个数
返回整型。
查询实体个数的数据层实现中,与查询实体列表的实体层实现保持一致。框架内部会自动转换为数据行数的查询。
[RepositoryQuery] public virtual long CountByDate(DateTime date) { var q = this.CreateLinqQuery(); q = q.Where(e => e.CreateTime >= date); return (long)this.QueryData(q); }查询表格数据
可返回一个简单的表格类型数据。LiteDataTable 类型是一个可直接用于网络传输的数据表格。
根据 Command Query Responsibility Segregation(命令查询职责分离,简称 CQRS)模式,复杂查询一般使用表格查询,但是返回的数据只做只读查看,不支持修改。
[RepositoryQuery] public virtual LiteDataTable GetTableByName(string name) { FormattedSql sql = "SELECT * FROM WAREHOUSE WHERE NAME = {0}"; sql.Parameters.Add(name); return (this.DataQueryer as RdbDataQueryer).QueryTable(sql); }
实体查询实现方式
对于实体的查询的实现方式,目前支持以下查询方式: