C# 在使用实体框架时实现业务逻辑
我不熟悉实体框架,对如何实现业务逻辑感到困惑 我使用代码优先的方法,并生成了我的POCO。我将它们放在一个单独的项目中,以便可以在多个项目中使用 我想知道如何为一个对象实现业务逻辑,当我试图将一个项目保存到数据库时,会检查该逻辑。例如,如果我定义了一个规则,即除非输入名称,否则无法保存MyObject,那么我该怎么做 简单POCO示例C# 在使用实体框架时实现业务逻辑,c#,asp.net-mvc,entity-framework,C#,Asp.net Mvc,Entity Framework,我不熟悉实体框架,对如何实现业务逻辑感到困惑 我使用代码优先的方法,并生成了我的POCO。我将它们放在一个单独的项目中,以便可以在多个项目中使用 我想知道如何为一个对象实现业务逻辑,当我试图将一个项目保存到数据库时,会检查该逻辑。例如,如果我定义了一个规则,即除非输入名称,否则无法保存MyObject,那么我该怎么做 简单POCO示例 public class MyObject() { public String name { get; set; }; public MyObj
public class MyObject() {
public String name { get; set; };
public MyObject() {}
}
显然,我有很多对象,每个对象都有不同的业务规则
我来自Csla()业务框架背景,在这里定义了一个业务对象,它有一个Save方法。调用Save时,框架运行ValidationRules,从而确定是否需要调用数据库
我想要这样的东西,使用实体框架。最好是代码示例,或者参考阅读材料。谢谢我通常在我的应用程序中构建一个服务层来处理业务逻辑,它与我的数据访问层对话以持久化任何数据
public class JobService : IJobService
{
private readonly IJobRepository _jobRepository;
public JobService(IJobRepository jobRepository)
{
_jobRepository = jobRepository;
}
public IEnumerable<Job> GetAllJobs()
{
return _jobRepository.All().OrderBy(x => x.Name);
}
public Job GetJobById(Guid Id)
{
return _jobRepository.FindBy(x => x.Id == Id);
}
public void UpdateJob(Job job, User user)
{
job.LastUpdatedDate = DateTime.Now;
job.LastUpdatedBy = user;
_jobRepository.Update(job);
}
public void DeleteJob(Job job)
{
_jobRepository.Delete(job);
}
public void SaveJob(Job job, User user)
{
job.CreatedDate = DateTime.Now;
job.CreatedBy = user;
_jobRepository.Insert(job);
}
}
公共类JobService:IJobService
{
专用只读IJobRepository\u作业存储库;
公共JobService(IJobRepository jobRepository)
{
_jobRepository=jobRepository;
}
公共IEnumerable GetAllJobs()
{
返回_jobRepository.All().OrderBy(x=>x.Name);
}
公共作业GetJobById(Guid Id)
{
返回_jobRepository.FindBy(x=>x.Id==Id);
}
public void UpdateJob(作业作业,用户)
{
job.lastUpdateDate=DateTime.Now;
job.LastUpdatedBy=用户;
_jobRepository.Update(作业);
}
公共无效删除作业(作业作业)
{
_jobRepository.Delete(作业);
}
公共作废保存作业(作业作业,用户)
{
job.CreatedDate=DateTime.Now;
job.CreatedBy=用户;
_jobRepository.Insert(作业);
}
}
您的服务可以复杂到您想要的程度,同时仍然抽象出您的数据访问层。我不会向您的POCO类添加任何方法,因为这违背了POCO类的目的。服务也是验证业务规则的好地方。虽然我没有提供这样的示例,但是可以很容易地将验证添加到您的服务方法中
编辑
我在编写大型应用程序时通常使用的体系结构需要合同来定义数据访问层。我们使用接口定义类结构的原因是,我们可以以不同的方式实现它们,而无需更改使用这些类的任何代码。例如,您可以使用EF实现您的存储库模式,但稍后可能会发现您想要使用NHibernate。要进行更改,您只需更改存储库的实现,而不必更改实际使用存储库的代码
我的存储库合同通常如下所示:
/// <summary>
/// This interface is implemented by all repositories to ensure implementation of fixed methods.
/// </summary>
/// <typeparam name="TEntity">Main Entity type this repository works on</typeparam>
/// <typeparam name="TKey">Primary key type of the entity</typeparam>
public interface IRepository<TKey, TEntity> : IRepository where TEntity : class, IEntity<TKey>
{
/// <summary>
/// Inserts a new entity.
/// </summary>
/// <param name="entity">Entity to insert</param>
TEntity Insert(TEntity entity);
/// <summary>
/// Inserts multiple entities.
/// </summary>
/// <param name="entities">Entities to insert</param>
IEnumerable<TEntity> Insert(IEnumerable<TEntity> entities);
/// <summary>
/// Updates an existing entity.
/// </summary>
/// <param name="entity">Entity</param>
TEntity Update(TEntity entity);
/// <summary>
/// Updates or saves an entity
/// </summary>
/// <param name="entity">Entity</param>
TEntity SaveOrUpdate(TEntity entity);
/// <summary>
/// Deletes an entity.
/// </summary>
/// <param name="id">Id of the entity</param>
bool Delete(TKey id);
/// <summary>
/// Deletes an entity.
/// </summary>
/// <param name="entity">Entity to be deleted</param>
bool Delete(TEntity entity);
/// <summary>
/// Deletes an entity.
/// </summary>
/// <param name="entities">Entities to be deleted</param>
bool Delete(IEnumerable<TEntity> entities);
/// <summary>
/// Used to get an IQueryable that is used to retrieve entities from entire table.
/// </summary>
/// <returns>IQueryable to be used to select entities from database</returns>
IQueryable<TEntity> All();
/// <summary>
/// Gets an entity.
/// </summary>
/// <param name="expression">LINQ expression used to evaluate and find an entity</param>
/// <returns>Entity</returns>
TEntity FindBy(Expression<Func<TEntity, bool>> expression);
/// <summary>
/// Used to get an IQueryable that is used to retrieve entities from evaluated LINQ expression.
/// </summary>
/// <param name="expression">LINQ expression used to evaluate and find entities</param>
/// <returns>IQueryable to be used to select entities from database</returns>
IQueryable<TEntity> FilterBy(Expression<Func<TEntity, bool>> expression);
/// <summary>
/// Gets an entity.
/// </summary>
/// <param name="id">Primary key of the entity to get</param>
/// <returns>Entity</returns>
TEntity FindBy(TKey id);
}
//
///此接口由所有存储库实现,以确保固定方法的实现。
///
///此存储库工作的主实体类型
///实体的主键类型
公共接口IRepository:IRepository,其中tenty:class,ienty
{
///
///插入一个新实体。
///
///要插入的实体
TEntity插件(TEntity实体);
///
///插入多个实体。
///
///要插入的实体
IEnumerable Insert(IEnumerable实体);
///
///更新现有实体。
///
///实体
TEntity更新(TEntity实体);
///
///更新或保存实体
///
///实体
TEntity SaveOrUpdate(TEntity实体);
///
///删除一个实体。
///
///实体的Id
bool Delete(TKey id);
///
///删除一个实体。
///
///要删除的实体
bool-Delete(TEntity实体);
///
///删除一个实体。
///
///要删除的实体
bool Delete(IEnumerable实体);
///
///用于获取用于从整个表检索实体的IQueryable。
///
///i可用于从数据库中选择实体
IQueryable All();
///
///获取一个实体。
///
///用于计算和查找实体的LINQ表达式
///实体
TEntity FindBy(表达式);
///
///用于获取用于从计算的LINQ表达式检索实体的IQueryable。
///
///用于计算和查找实体的LINQ表达式
///i可用于从数据库中选择实体
可计量过滤器(表达式);
///
///获取一个实体。
///
///要获取的实体的主键
///实体
TEntity FindBy(TKey id);
}
然后,您可以访问存储库:
// We create separate repositories inheriting from IRepository in case we need specific repository methods for that entity
public interface IJobRepository : IRepository<Guid, Job>
{
}
//我们创建从IRepository继承的独立存储库,以防我们需要该实体的特定存储库方法
公共接口IJobRepository:IRepository
{
}
如何实现存储库取决于您,但通常对于EF,您会向存储库传递一个DbSet或DbContext,并对其执行操作
您的服务合同将取决于您的业务逻辑。某些实体可能只需要从持久存储中读取。其他,您将不得不使用服务方法来验证/插入/操作/等等
当您使用控制反转(InversionofControl,IoC)将这些契约的实现作为构造函数参数注入时,这种设计模式最为有效。我通常使用Castle Windsor,但是有很多IoC依赖注入框架。你不能在项目之间拆分部分类,所有的部分意味着一个类可以在多个源代码文件中定义,这不是扩展现有类的一种方式。这是一个有趣的问题,但有点太广泛了,你能试着把你的问题缩小到……用更少的时间回答的问题吗