使用Entity Framework和WCF Ria Services开发SilverLight之2:POCO

在上一篇中《使用Entity Framework和WCF Ria Services开发SilverLight之1:简单模型》我们提出这类简单模型的几个问题:

1:实体模型被紧耦合在EDM中,同时它不能项目(模块)使用。随着每一次更新EDM,实体模型会被覆盖;

2:EDM和BLL紧耦合在一起;

3:没有提炼出数据接口,导致我们没有办法在此示例中进行单元测试。示例中虽然存在测试项目,但那是数据库相关的,达不到单元测试的要求;

1:创建POCO

本篇我们主要来解决第一个问题,那就是在EF中使用Plain Old CLR Object(简称POCO)。POCO是我们最熟悉不过实体模型。本示例所用的数据中Department的POCO形式为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Department
{
    public int DepartmentID { get; set; }
    public string Name { get; set; }
    public decimal Budget { get; set; }
    public DateTime StartDate { get; set; }
    public int Administrator { get; set; }
 
    public List<Course> Courses { get; set; }
 
    public void AddCourse(Course course)
    {
        if (Courses == null)
        {
            Courses = new List<Course>();
        }
 
        if (!Courses.Contains(course))
        {
            Courses.Add(course);
        }
 
        course.Department = this;
    }
}

如果不使用POCO,我们可以在EDM的后台代码中找到这个类的定义,它看上去增加了很多Attribute,并且复杂多了。

为了便于实体模型被更多的项目使用,我们为提升所有的实体模型到一个新创建的项目中,名为SchoolModel。

2:使用EF创建数据访问层

在本篇中,我们不打算再把数据访问耦合在WEB中,而是为其新建了一个项目,名为SchoolData。现在,我们已经创建了本篇所要展示的4个项目,如下:

image

接着,我们按照第一篇中步骤,在SchoolData中创建EDM。由于本文已经采用POCO,所以我们必须关闭EF自动为我们的EDM生成实体模型。要关闭代码生成,在Model.edmx上点属性,然后,清楚自定义工具中的内容。

image

关闭代码生成后,我们会发现EDM的后台文件消失了。

接着,手动创建SchoolContext,完成数据库操作。如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class SchoolContext : ObjectContext
{
    static string conn = "metadata=res://*/ModelSchool.csdl|res://*/ModelSchool.ssdl|res://*/ModelSchool.msl;provider=System.Data.SqlClient;provider connection string=\"Data Source=hzh-pc\\sqlexpress;Initial Catalog=School;Persist Security Info=True;User ID=sa;Password=sasa\"";
    public SchoolContext()
        : base(conn, "SchoolEntities")
    {
        _courses = CreateObjectSet<Course>();
        _departments = CreateObjectSet<Department>();
    }
 
    private ObjectSet<Course> _courses;
    public ObjectSet<Course> Courses
    {
        get
        {
            return _courses;
        }
    }
 
    private ObjectSet<Department> _departments;
    public ObjectSet<Department> Departments
    {
        get
        {
            return _departments;
        }
    }
 
}

(你应该修改conn,以满足你的开发设置)。到目前为止,我们知道,项目SchoolModel可以被任何其它项目使用,SchoolData也同样,它即可以被WEB引用作为RIA SERVICE公开给SL APP,也可以被类似Winform的项目使用,这很COOL,离我们的目标越来越近了。

3:创建Ria Service

本步骤,我们仍旧将DomainService创建在WEB中,名为DomainServiceSchool。

image

由于我们已经把数据访问层,也就是EF解耦出去了,所以我们无法和在第一篇中一样,在这里选择DataContext了。没有关系,确保选择“Enable client access”,点OK。

这个时候我们去查看DomainServiceSchool,由于它已经不直接从EF中获取数据(确切滴说,它也不应该知道数据访问层通过什么来获取数据),所以它的基类,已经从LinqToEntitiesDomainService<SchoolContext>变为DomainService。

4:DomainServiceSchool从数据访问层SchoolData获取数据

DomainService不会再直接从SchoolContext获取数据,也就是说,DAL需要负责公开自己的数据接口给DomainServiceSchool。比如,为了获取Department数据,我们需要在DAL中创建一个类型DepartmentRepository,由该类型负责向DomainServiceSchool公开数据接口。DepartmentRepository的实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class DepartmentRepository : IDepartmentRepository
{
    SchoolContext _schoolContext;
    public DepartmentRepository()
    {
        _schoolContext = new SchoolContext();
    }
    public DepartmentRepository(SchoolContext schoolContext)
    {
        _schoolContext = schoolContext;
    }
 
    public Department GetDepartmentById(int id)
    {
        return _schoolContext.Departments.Where( d => d.DepartmentID == id).Single();
    }
 
    public IEnumerable<Department> GetAll()
    {
        return _schoolContext.Departments;
    }
 
    public void AddDepartment(Department department)
    {
        _schoolContext.Departments.AddObject(department);
    }
}

接着,我们在DomainServiceSchool调用它,如下:

1
2
3
4
5
6
7
8
9
10
11
[EnableClientAccess()]
public class DomainServiceSchool : DomainService
{
 
    public IEnumerable<Department> GetDepartments()
    {
        DepartmentRepository cr = new DepartmentRepository();
        return cr.GetAll();
    }
 
}

5:小结

SL APP部分和第一篇一样,本篇不在赘述。

本篇源码下载:SilverlightApplication20110612.zip(要让程序可以运行,需要安装第一篇中的数据库)

通过以上的改造,我们的系统架构呈现这样的形式:

image

1:SchoolData(DAL),SchoolModel(Object Model),作为公共模块,可以提供给其它调用方;

2:Winform或者Web作为模块的消费者;

3:SilverLight通过Ria Services消费Web中的DomainService。

posted @   陆敏技  阅读(4454)  评论(13编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
Web Counter
Coupon for Contacts
点击右上角即可分享
微信分享提示