创建Presentation Model 类
Presentation Model类用于如下情况:
1)在应用程序中不使用EF model;
2)不想让显示层与数据访问层进行共享,保持两层之间的独立性;
3)模块中的实体与显示层并不是一对一的匹配关系,显示的数据可能是多个实体聚合的结果;
4)需要统计数据(求和,平均等);
5)需要格式化数据从而适合显示界面;
创建Presentation Model类步骤如下:
- 构建类,包含所有需要在客户端显示的属性;
- 构建域服务类,继承自DomainService;
- 手工配置get/query域操作,暴露给Presentation model;
- 需要进行数据编辑,手工实现insert/update/delete操作
实例:
1、注意事项:
- 至少有一个属性以Key特性修饰,指定其为主键;
- 可以使用所有修饰特性标记;如果不想在类上修饰,也可以建立相应的元数据类,添加相应的修饰;
- Presentation model类可以根据需要放置在解决方案中的适当项目中,不限于Web项目中;
2、具体实现
1)在Web项目的Models文件夹下创建一个新类,命名为ProductSummary。
2)向类中添加适当引用,添加相应属性,代码如下:
using System; using System.ComponentModel.DataAnnotations; namespace AdventureWorks.Web.Models { public class ProductSummary { [Key] [Editable(false)] public int ID { get; set; } public string Name { get; set; } public string Number { get; set; } public decimal ListPrice { get; set; } public byte[] ThumbnailPhoto { get; set; } public int? QuantityAvailable { get; set; } public string Category { get; set; } public string Subcategory { get; set; } public string Model { get; set; } public bool MakeFlag { get; set; } public DateTime ModifiedDate { get; set; } } }
3、填充或暴露Presentation Model类型:
1)在Web项目的Service文件夹,使用Domain Service Class项目模板,添加一个名为ProductSummaryService的域服务类。因为数据仍然是取自于实体模型,因此需要选择AdventureWorksEntities实体模型作为对象上下文。不要选择实体列表中的任何实体,只需要点击OK按钮。这就创建了空白的域服务:
namespace AdventureWorks.Web.Services { using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Data; using System.Linq; using System.ServiceModel.DomainServices.EntityFramework; using System.ServiceModel.DomainServices.Hosting; using System.ServiceModel.DomainServices.Server; using AdventureWorks.Web; // Implements application logic using the AdventureWorksEntities context. // TODO: Add your app logic to these methods or in additional methods. // TODO: Wire up authentication (Windows/ASP.NET Forms) and uncomment the // following to disable anonymous access. // Also consider adding roles to restrict access as appropriate. // [RequiresAuthentication] [EnableClientAccess()] public class ProductSummaryService : LinqToEntitiesDomainService{ } }
2)添加对AdventureWorks.Web.Models名称空间的引用;
3)向域服务中添加查询操作,要求返回IQueryable集合类型:
public IQueryableGetProductSummaryList() { return from p in this.ObjectContext.Products select new ProductSummary() { ID = p.ProductID, Name = p.Name, Number = p.ProductNumber, ListPrice = p.ListPrice, ThumbnailPhoto = p.ProductProductPhotoes.FirstOrDefault(). ProductPhoto.ThumbNailPhoto, QuantityAvailable = p.ProductInventories .Sum(pi => pi.Quantity), Category = p.ProductSubcategory.ProductCategory.Name, Subcategory = p.ProductSubcategory.Name, Model = p.ProductModel.Name, MakeFlag = p.MakeFlag, ModifiedDate = p.ModifiedDate }; }
4、编辑Presentation Model
1)Insert,Update,Delete域操作方法的命名与签名与前述要求一致:
public void InsertProductSummary(ProductSummary productSummary) { } public void UpdateProductSummary(ProductSummary productSummary) { } public void DeleteProductSummary(ProductSummary productSummary) { }
2)Insert方法实现:
public void InsertProductSummary(ProductSummary productSummary) { Product product = new Product(); product.Name = productSummary.Name; product.ProductNumber = productSummary.Number; product.ListPrice = productSummary.ListPrice; product.ModifiedDate = DateTime.Now; // Need to set default values for these properties, // otherwise the save will fail product.SellStartDate = DateTime.Now; product.SafetyStockLevel = 1; product.ReorderPoint = 1; this.ObjectContext.Products.AddObject(product); }
3)Update方法实现
public void UpdateProductSummary(ProductSummary productSummary) { Product product = this.ObjectContext.Products .Where(p => p.ProductID == productSummary.ID) .First(); product.Name = productSummary.Name; product.ProductNumber = productSummary.Number; product.ListPrice = productSummary.ListPrice; product.ModifiedDate = DateTime.Now; }
4)删除方法实现:
public void DeleteProductSummary(ProductSummary productSummary) { Product product = new Product(); product.ProductID = productSummary.ID; product.ModifiedDate = productSummary.ModifiedDate; this.ObjectContext.AttachTo("Products", product); this.ObjectContext.DeleteObject(product); }
4、将自动生成属性值返回客户端
当插入(或更新)数据到服务器后,通常需要将保存的数据再返回到客户端,可以通过域服务的ChangeSet对象的Associate方法实现。下面的实例介绍的场景是:向数据库插入一条新记录以后,刚刚更新的Product实体的ProductId与ModifiedDate属性值返回客户端,更新ProductSummary对象:
1)在ProductSummaryService类中添加如下的回调方法。该方法将更新ProductSummary对象的ProductId与ModifiedDate属性,返回值到客户端:
private void UpdateProductSummaryValues(ProductSummary productSummary, Product product) { productSummary.ID = product.ProductID; productSummary.ModifiedDate = product.ModifiedDate; }
2)调用ChangeSet对象的Associate方法,通知回调方法的调用时机为Product实体持久化数据库之后:
public void InsertProduct(ProductSummary productSummary) { Product product = new Product(); product.Name = productSummary.Name; product.ProductNumber = productSummary.Number; product.ListPrice = productSummary.ListPrice; product.ModifiedDate = DateTime.Now; // Need to set default values for these properties, // otherwise the save will fail. product.SellStartDate = DateTime.Now; product.SafetyStockLevel = 1; product.ReorderPoint = 1; this.ObjectContext.Products.AddObject(product); this.ObjectContext.SaveChanges(); ChangeSet.Associate(productSummary, product, UpdateProductSummaryValues); }