Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在没有存储库模式的情况下实现服务层和验证_C#_Entity Framework_Repository Pattern - Fatal编程技术网

C# 如何在没有存储库模式的情况下实现服务层和验证

C# 如何在没有存储库模式的情况下实现服务层和验证,c#,entity-framework,repository-pattern,C#,Entity Framework,Repository Pattern,我想使用实体框架和WinForms构建一个简单的酒店预订系统。我到处都读到EF已经实现了repository模式,DbContext是UoW,每个DbSet都是一个存储库,因此使用RP会让事情变得有点多余。那么,如何跳过它并使用服务层呢?此服务中驻留何种操作,以及在查询数据库之前在何处验证对象? 我认为我应该这样做: public class ReservationService : //(Some useful interface should be here, what do you su

我想使用实体框架和WinForms构建一个简单的酒店预订系统。我到处都读到EF已经实现了repository模式,DbContext是UoW,每个DbSet都是一个存储库,因此使用RP会让事情变得有点多余。那么,如何跳过它并使用服务层呢?此服务中驻留何种操作,以及在查询数据库之前在何处验证对象? 我认为我应该这样做:

public class ReservationService : //(Some useful interface should be here, what do  you suggest?)
{
    public void MakeReservation(Reservation reservation)
    {
        //Validate reservation
        //Save reservation
    }
    public IEnumerable<Reservation> GetReservationsByDate(DateTime date)
    {
        //Linq queries
    }
    public IEnumerable<Reservation> GetReservationsByName(string name)
    {
        //Linq queries
    }
    public IEnumerable<Room> GetRoomsAvailable()
    {
        //Linq queries
    }
    public IEnumerable<Room> GetRoomsAvailableByDate(DateTime date)
    {

    }
}
公共类ReservationService://(这里应该有一些有用的接口,您有什么建议?)
{
公共预订(预订)
{
//确认预订
//保存预订
}
公共IEnumerable GetReservationsByDate(日期时间日期)
{
//Linq查询
}
public IEnumerable GetReservationsByName(字符串名称)
{
//Linq查询
}
公共IEnumerable GetRoomsAvailable()
{
//Linq查询
}
公共IEnumerable GetRoomsAvailableByDate(日期时间日期)
{
}
}
编辑:以下是我实施验证的方式:

public class ReservationValidator : Validator<Reservation>
{
    public ReservationValidator()
    {
        this.Errors = new Dictionary<string, string>();
    }
    public override bool Validate(Reservation reservation)
    {
        if (logic here)
            this.Errors.Add("somePropertyName", "someMessage");
        if (Errors.Count > 0)
        {
            return false;
        }
        return true;
    }
}
公共类ReservationValidator:Validator
{
公共ReservationValidator()
{
this.Errors=newdictionary();
}
公共覆盖bool验证(预订)
{
if(此处为逻辑)
this.Errors.Add(“somePropertyName”、“someMessage”);
如果(Errors.Count>0)
{
返回false;
}
返回true;
}
}

如果在接口后面使用通用存储库模式,那么您可以轻松地测试可重用代码。您的存储库实现将公开相关查询。测试时,可以为内存中的集合切换出底层数据存储。如果您依赖于强类型化到模型中的dbcontext,那么测试将变得更加困难,并且依赖于DB查询。比如说

 public interface IRepository<T,TId>{

 T GetById(TId id);

  Etc etc

  } 
公共接口IRepository{
T GetById(TId id);
等等
} 
对于您的数据库访问:

Public class MyConcreteDbRepos<T,TId> : IRepository<T,TId>{
      Implementation here
}
公共类MyConcreteDbRepos:IRepository{
在这里实现
}
对于您的测试:

Public class MyInMemoryRepos<T,TId> : IRepository<T,TId>{
   Implantation here
}
公共类MyInMemoryRepos:IRepository{
此处植入
}
此实现依赖于您自己的工作单元来持有您的数据库集的回购(为简洁起见省略)。如果抽象太重,就不必这样做。您可以通过这些方法公开泛型方面,并让一个repo包含dbcontext。通常可以从dbcontext中选择dbset


主要的一点是不要依赖实体框架来为您完成这一切。界面和设计模式可以帮助您编写非常独立的软件,这些软件更易于测试和长期维护。

在我看来还可以。我会将验证移到上层,因此如果出现问题,只需告诉用户验证失败,并在一切正常的情况下调用该服务。但是如果我想在Web ui中使用该服务,这意味着我必须正确重写验证,该怎么办?或者我应该做一个单独的验证项目吗?只需在单独的类中提取验证。这样,您就可以在不同的项目中使用它。看一看Spring验证器(只是为了了解这个想法):您可以编写类似的类来接受和对象并返回验证错误。正如我所说的,我不想通过在EF上添加其他层来使事情复杂化,如果存储库中只有一行代码,则无需添加方法,例如GetById方法,它将具有如下内容:context.Reservations.Find(id),对于服务层可以处理的更复杂的查询,我的问题是如何省略存储库模式,而只使用服务层以及将验证放在何处。您的服务代码说它应该实现某种接口?我只是提供我在生产中使用过的东西。当我们后来不得不添加一些东西时,它产生了巨大的变化。它更容易测试。另一个好处是可以使用扩展方法编写特定于实体的查询。验证应该在业务对象中进行,然后再进行持久性验证。您的服务层提供服务,因此如果您愿意,也可以在这里进行验证。