5 c# wcf design-patterns entity-framework
假设我们有一个项目可以处理大量数据(员工,日程安排,日历等等).客户端是Windows App,服务器端是WCF.数据库是MS SQL Server.关于使用哪种方法我很困惑.我看了几篇文章和博客,他们看起来都很好,但我很困惑.我不想从一种方法开始,然后后悔没有选择另一种方法.该项目将有大约30-35种不同的对象类型.大量数据检索以填充不同的报告......等
方法1:
// classes that hold data
public class Employee
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
.....
}
public class Assignment
{
public int Id { get; set; }
public int UserId { get; set; }
public DateTime Date { get; set; }
.....
}
.....
Run Code Online (Sandbox Code Playgroud)
然后帮助类处理数据保存和检索:
public static class Employees
{
public static int Save(Employee emp)
{
// save the employee
}
public static Employee Get(int empId)
{
// return the ugly employee
}
.....
}
public static class Assignments
{
public static int Save(Assignment ass)
{
// save the Assignment
}
.....
}
Run Code Online (Sandbox Code Playgroud)
仅供参考,像Employees和Assignment这样的对象类将在Sever和Client之间共享一个单独的程序集中.无论如何,通过这种方法,我将有一个更清洁的对象.助手课程将完成大部分工作.
方法2:
// classes that hold data and methods for saving and retrieving
public class Employee
{
// constructors
public Employee()
{
// Construct a new Employee
}
public Employee(int Id)
{
// Construct a new Employee and fills the data from db
}
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
.....
public int Save()
{
// save the Employee
}
.....
}
public class Assignment
{
// constructors
public Assignment()
{
// Construct a new assignment
}
public Assignment(int Id)
{
// Construct a new assignment and fills the data from db
}
public int Id { get; set; }
public int UserId { get; set; }
public DateTime Date { get; set; }
.....
public int Save()
{
// save the Assignment
}
.....
}
.....
Run Code Online (Sandbox Code Playgroud)
使用这种方法,每个对象都可以自己完成工作.由于WCF只共享属性,因此数据仍然可以轻松地从WCF传输到客户端.
方法3:
使用实体框架..除了我从未使用它的事实(这很好,因为我必须学习新东西)我将需要创建POCO以在客户端和WCF之间传输数据.
现在,哪个更好?更多的选择?
我建议使用实体框架+存储库模式。这样,您的实体就是简单的对象,其中没有任何逻辑。所有检索-保存逻辑都保留在存储库中。我在使用通用存储库方面有一些成功的经验,它是用实体输入的,这里描述了类似的东西(本文的通用存储库部分)。这样,您只需编写一次存储库代码,就可以将其重用于您拥有的所有实体。例如:
interface IRepositry<T>
{
T GetById(long id);
bool Save(T entity);
}
public class Repository<T> : IRepository<T> {...}
var repository = new Repository<MyEntity>();
var myEntity = repository.GetById(1);
var repository2 = new Repository<MySecondEntity>();
var mySecondEntity = repository.GetById(1);
Run Code Online (Sandbox Code Playgroud)
每当实体需要一些非常具体的操作时,您可以将此操作添加到 IRepository 的具体类型实现中:
interface IMySuperRepositry : IRepository<MySuperEntity>
{
MySuperEntity GetBySuperProperty(SuperProperty superProperty);
}
public class MySuperEntityRepository : Repository, IMySuperRepository
{...}
Run Code Online (Sandbox Code Playgroud)
要创建存储库,最好使用工厂,它基于例如配置文件。这样,当您不想使用真正访问数据库的存储库时,您可以切换存储库的实现,例如用于单元测试:
public class RepositoryFactory
{
IRepository<T> GetRepository<T>()
{
if (config == production)
return new Repository<T>(); // this is implemented with DB access through EF
if (config == test)
return new TestRepository<T>(); // this is implemented with test values without DB access
}
}
Run Code Online (Sandbox Code Playgroud)
} }
您可以添加保存验证规则并进一步详细说明。EF 还允许您向生成的实体添加一些简单的方法或属性,因为它们都是分部类。
此外,使用 POCO 或 STE(见下文)可以在一个项目中拥有 EDMX DB 模型,而在另一个项目中拥有所有实体,从而将此 DLL 分发到客户端(该客户端将仅包含您的实体)。据我了解,这也是您想要实现的目标。
还要认真考虑使用自我跟踪实体(而不仅仅是 POCO)。在我看来,它们非常适合与 WCF 一起使用。当您从数据库获取实体并将其传递给客户端时,客户端更改它并将其返回,您需要知道实体是否已更改以及更改了什么。STE 会为您处理所有这些工作,并且是专为 WCF 设计的。您从客户端获取实体,例如ApplyChanges 和Save,就是这样。