哪种设计更适合具有大量数据共享的客户端/服务器项目

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之间传输数据.

现在,哪个更好?更多的选择?

Max*_*ikh 0

我建议使用实体框架+存储库模式。这样,您的实体就是简单的对象,其中没有任何逻辑。所有检索-保存逻辑都保留在存储库中。我在使用通用存储库方面有一些成功的经验,它是用实体输入的,这里描述了类似的东西(本文的通用存储库部分)。这样,您只需编写一次存储库代码,就可以将其重用于您拥有的所有实体。例如:

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,就是这样。