使用Entity Framework和WCF Ria Services開發(fā)SilverLight之2:POCO
在上一篇中《使用Entity Framework和WCF Ria Services開發(fā)SilverLight之1:簡單模型》我們提出這類簡單模型的幾個(gè)問題:
1:實(shí)體模型被緊耦合在EDM中,同時(shí)它不能項(xiàng)目(模塊)使用。隨著每一次更新EDM,實(shí)體模型會(huì)被覆蓋;
2:EDM和BLL緊耦合在一起;
3:沒有提煉出數(shù)據(jù)接口,導(dǎo)致我們沒有辦法在此示例中進(jìn)行單元測試。示例中雖然存在測試項(xiàng)目,但那是數(shù)據(jù)庫相關(guān)的,達(dá)不到單元測試的要求;
1:創(chuàng)建POCO
本篇我們主要來解決第一個(gè)問題,那就是在EF中使用Plain Old CLR Object(簡稱POCO)。POCO是我們最熟悉不過實(shí)體模型。本示例所用的數(shù)據(jù)中Department的POCO形式為:
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的后臺(tái)代碼中找到這個(gè)類的定義,它看上去增加了很多Attribute,并且復(fù)雜多了。
為了便于實(shí)體模型被更多的項(xiàng)目使用,我們?yōu)樘嵘械膶?shí)體模型到一個(gè)新創(chuàng)建的項(xiàng)目中,名為SchoolModel。
2:使用EF創(chuàng)建數(shù)據(jù)訪問層
在本篇中,我們不打算再把數(shù)據(jù)訪問耦合在WEB中,而是為其新建了一個(gè)項(xiàng)目,名為SchoolData。現(xiàn)在,我們已經(jīng)創(chuàng)建了本篇所要展示的4個(gè)項(xiàng)目,如下:
接著,我們按照第一篇中步驟,在SchoolData中創(chuàng)建EDM。由于本文已經(jīng)采用POCO,所以我們必須關(guān)閉EF自動(dòng)為我們的EDM生成實(shí)體模型。要關(guān)閉代碼生成,在Model.edmx上點(diǎn)屬性,然后,清楚自定義工具中的內(nèi)容。
關(guān)閉代碼生成后,我們會(huì)發(fā)現(xiàn)EDM的后臺(tái)文件消失了。
接著,手動(dòng)創(chuàng)建SchoolContext,完成數(shù)據(jù)庫操作。如下:
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;
}
}
}
(你應(yīng)該修改conn,以滿足你的開發(fā)設(shè)置)。到目前為止,我們知道,項(xiàng)目SchoolModel可以被任何其它項(xiàng)目使用,SchoolData也同樣,它即可以被WEB引用作為RIA SERVICE公開給SL APP,也可以被類似Winform的項(xiàng)目使用,這很COOL,離我們的目標(biāo)越來越近了。
3:創(chuàng)建Ria Service
本步驟,我們?nèi)耘f將DomainService創(chuàng)建在WEB中,名為DomainServiceSchool。
由于我們已經(jīng)把數(shù)據(jù)訪問層,也就是EF解耦出去了,所以我們無法和在第一篇中一樣,在這里選擇DataContext了。沒有關(guān)系,確保選擇“Enable client access”,點(diǎn)OK。
這個(gè)時(shí)候我們?nèi)ゲ榭碊omainServiceSchool,由于它已經(jīng)不直接從EF中獲取數(shù)據(jù)(確切滴說,它也不應(yīng)該知道數(shù)據(jù)訪問層通過什么來獲取數(shù)據(jù)),所以它的基類,已經(jīng)從LinqToEntitiesDomainService<SchoolContext>變?yōu)镈omainService。
4:DomainServiceSchool從數(shù)據(jù)訪問層SchoolData獲取數(shù)據(jù)
DomainService不會(huì)再直接從SchoolContext獲取數(shù)據(jù),也就是說,DAL需要負(fù)責(zé)公開自己的數(shù)據(jù)接口給DomainServiceSchool。比如,為了獲取Department數(shù)據(jù),我們需要在DAL中創(chuàng)建一個(gè)類型DepartmentRepository,由該類型負(fù)責(zé)向DomainServiceSchool公開數(shù)據(jù)接口。DepartmentRepository的實(shí)現(xiàn)如下:
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調(diào)用它,如下:
[EnableClientAccess()]
public class DomainServiceSchool : DomainService
{
public IEnumerable<Department> GetDepartments()
{
DepartmentRepository cr = new DepartmentRepository();
return cr.GetAll();
}
}
5:小結(jié)
SL APP部分和第一篇一樣,本篇不在贅述。
本篇源碼下載:SilverlightApplication20110612.zip(要讓程序可以運(yùn)行,需要安裝第一篇中的數(shù)據(jù)庫)
通過以上的改造,我們的系統(tǒng)架構(gòu)呈現(xiàn)這樣的形式:
1:SchoolData(DAL),SchoolModel(Object Model),作為公共模塊,可以提供給其它調(diào)用方;
2:Winform或者Web作為模塊的消費(fèi)者;
3:SilverLight通過Ria Services消費(fèi)Web中的DomainService。





浙公網(wǎng)安備 33010602011771號(hào)