四、数据检索
一般地,我们还可以执行一些读取操作,如下所示。
清单3—从数据库读取数据
{
PropertyInfo[] properties = typeof(T).GetProperties();
foreach (PropertyInfo property in properties)
{
EdmScalarPropertyAttribute attrib = property.GetCustomAttributes(typeof(EdmScalarPropertyAttribute), false).FirstOrDefault() as EdmScalarPropertyAttribute;
if (attrib != null && attrib.EntityKeyProperty)
return property.Name;
}
return null;
}
public virtual T Get(int key)
{
string prop = this.GetKeyProperty();
if (string.IsNullOrEmpty(prop))
return null;
var ctx = CreateContext();
return (T)ctx.GetObjectByKey(new EntityKey(this.GetFullEntitySetName(ctx),
prop, key));
}
public virtual IQueryable<T> GetAll(int pageIndex, int pageSize)
{
var ctx = CreateContext();
return ctx.CreateObjectSet<T>(this.GetFullEntitySetName(ctx)).OrderBy(this.GetDefaultSortingExpression())
.Skip(pageIndex * pageSize).Take(pageSize);
}
默认设计器生成的每个实体类都将把一组属性添加到它对应的每一个字段属性上。其中,EdmScalarPropertyAttribute拥有EntityKeyProperty设置,被设置为true,对应于实体的键字段。这就提供了一种灵活的方式来确定主键列而不需要使用一个lambda表达式手动指定。
跟踪分析到ObjectContext方法内部,你会发现通过使用实体集名称构造一个对象集合可以取得一个数据实体的所有结果。对象集可以使用LINQ扩展方法来按索引页和大小加以过滤,例如只取得一个包含20个对象的结果集。不幸的是,调用Skip和Take方法需要先对对象进行排序。同样,你需要使用一个自定义Lambda表达式来执行这个排序操作。
GetObjectByKey方法实际上使用它的键从它的数据库中检索对象。我们可以利用我们的新的GetKeyProperty反射方法来获取主键属性的名称。正如你所看到的,我们不能直接使用这个键而需要使用一个EntityKey对象来检索它。
五、最终实现
我可以利用一个类似下面的信息库,并且已经在基类中实现了Create、Delete、Update、Get和GetAll方法。我们只需要关心的是,实现其他的查询操作。
清单4—最终版本的数据仓库类(其他其他前面已列举的内容)
{
protected override Expression<Func<DA.Product, object>> GetDefaultSortingExpression()
{
return j => j.ProductID;
}
protected override string GetEntitySetName(DA.DotNetSamplesObjectContext context)
{
return context.Products.EntitySet.Name;
}
}
在大多数情况下,代码生成将是最好的选择,有助于减少重复代码,但是,实体框架做了大量的内部基础工作(实现基础代码的自动生成)来实现这些特征支持而无需我们编写任何代码。
六、结论
ADO.NET实体框架提供了大量基础功能,节省了开发人员大量的代码编写时间。在本文中,我们讨论了ObjectContext类提供给我们的许多方法,其中包括从后端数据库获取和存入数据,等等。
最后,我们有理由相信,ADO.NET实体框架必将在ASP.NET MVC框架应用程序开发的数据管理模型开发中发挥越来越大的作用。