WCF+Ef实战系列二:EF实体的构建及数据业务层的处理
第一步我们来创建相关的数据库NewWide,里面有一张表Employees,如下图
列名 |
数据类型 |
可为空 |
长度 |
OID |
Int |
主键 自动增长 |
|
UserCode |
Nvarchar |
|
10 |
UserName |
Nvarchar |
|
20 |
PWD |
Nvarchar |
|
40 |
IsAdmin |
Bit |
|
|
有关EF建模及其理论的部分,可以参考如下:
http://www.cnblogs.com/foundation/ 的ADO.NET Entity Framework系列的5篇文章。在此我就不再废话了。但是有一点基本常识就是在建模时表一定要有主键.
建立一个项目如Demo.EDM.同时添加一个新项Ado.NET Entity Data Model.
选择从数据库生成,
选择你需要的结构,如表,Sp等。这里由于是DEMO,因此只选择Employees表。当然如果你以后在数据库里添加了新的对象,那你可以通验证EDM来导入新的对象。最终设计器显示为
已帮我们生成了我们所需要的模型了。你可以对些模型进行修改。当然是右键属性设置了。如设为不可为空,或映射名等。这里我不做修改了。http://www.cnblogs.com/foundation/ 的文章已说的很详细了。不理解的话可以再去看看。
在上图我们可以看到生成的模型对象的名称为Employees.这个是会让人误解的。因为我们一般实体对象是单数形式,而集合对象才以复式存在的。如员工应该是Employee,而员工集合才是Employees.因此只里我们需要改动一下。
关于MyEDM.edmx这个还有个属性值得注意的,就是元数据项目处理这块,你可以选择复制到输出目录。
Entity Data Model 是一个概念模型,所有Entity SQL和LINQ to Entities 查询将最终转化为T-SQL的脚本,从数据库中查询数据。与LINQ to SQL比较而言,ObjectContext 类没有提供Log属性或者通用的log机制,因此,无法在Visual Studio 中跟踪所有的T-SQL语句。
如果你想查看所有执行的T-SQL语句你需要使用SQL Server的Profiler 工具.或者EntityCommand和ObjectQuery类都有一个ToTraceString() 方法,第三种就是微软也提供了一个免费的工具来帮助学习Entity SQL。
eSqlBlast 的下载地址(含有源代码,需要自己编译一下)及其相关介绍(eSqlBlast for VS 2008 SP1):
http://code.msdn.microsoft.com/esql/Release/ProjectReleases.aspx?ReleaseId=991
而此工具在使用时需要获取3个元数据文件(CSDL/SSDL/MSL)。而刚才的选项可以生成此三个元数据文件。
此项目中的app.config文件里包含了EF在运行时需要的连接字符串,这个暂时不需要,但不要删除。后面在运行时还是需要的。
到此为止,我们实现的数据访问层的处理。是不是很简单。下面我们来讲一下业务层的处理。
当然我们这里的业务很简单,不存在一些逻辑的计算。只是调用数据访问层来实现Employee对象的增删改查。
再增加一个类库Demo. BusinessManagers.同时添加Demo.EDM的引用。
代码如下:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using System.Linq;
using System.Text;
using Demo.EDM;
using System.Data.EntityClient;
namespace Demo.BusinessManagers
{
public class EmployeeManager:IDisposable
{
newwideEntities context;
public EmployeeManager()
{
context = new newwideEntities();
}
public void Add(Employee emp)
{
context.AddToEmployees(emp);
context.SaveChanges();
}
public void Update(Employee emp)
{
context.Attach(emp); //不是新增。因此先附加
emp.SetAllModified(context); //由于此emp对象是客户端上传上来的。附加后,对象的状态不存在更新标记。因此这里设置其为更新状态。如果不更改状态,则不会生成相应的SQL
context.SaveChanges();
}
public void Delete(Employee emp)
{
//如果要删除一个对象的话,先附加此对象,因为EF有个跟踪机制存在。如果不这样处理,则只能先select first 再delete 这样会引起二次SQL语句
context.Attach(emp);
context.DeleteObject(emp);
context.SaveChanges();
}
public List<Employee> GetEmployees()
{
return context.Employees.ToList();
}
#region IDisposable 成员
public void Dispose()
{
context.Dispose();
}
#endregion
}
public static class EFExtension
{
//通知对象的属性状态改变
public static void SetAllModified<T>(this T entity, ObjectContext context) where T : IEntityWithKey
{
var stateEntry = context.ObjectStateManager.GetObjectStateEntry(entity.EntityKey);
var propertyNameList = stateEntry.CurrentValues.DataRecordInfo.FieldMetadata.Select(pn => pn.FieldType.Name);
foreach (var propName in propertyNameList)
{
stateEntry.SetModifiedProperty(propName);
}
}
}
}
好了。这样我们就可以实现EMPLOYEE的基本处理了。下一次,我们将实现关于员工的WCF服务。以便客户端能订阅该服务并调用