.net 实体框架:具有关系等的对象设计
我有一个关于大学管理的.net解决方案(使用实体框架,使用CodeFirst方法)。项目的架构如下所示:.net 实体框架:具有关系等的对象设计,.net,entity-framework,object-design,.net,Entity Framework,Object Design,我有一个关于大学管理的.net解决方案(使用实体框架,使用CodeFirst方法)。项目的架构如下所示: 数据访问(DbContext和通用存储库) 实体(代码优先类) 服务(服务类别) Web(一个MVC项目,解释起来并不重要) 为了使问题更简单,我将只讨论我的领域中的两个类(在实体层上): 课程 学生 这门课可以有很多学生。解决方案的目标是将学生添加到课程中(中间有一些验证) 课程.cs 公共课 { [关键] public int IdCourse{get;protected set
- 数据访问(DbContext和通用存储库)
- 实体(代码优先类)
- 服务(服务类别)
- Web(一个MVC项目,解释起来并不重要)
- 课程
- 学生
公共课
{
[关键]
public int IdCourse{get;protected set;}
公共字符串名称{get;set;}
公共虚拟ICollection学生{get;protected set;}
公立学校学生(学生)
{
//一些验证
学生。添加(学生);
}
}
如您所见,该类具有用于将学生添加到课程的属性。
目前的情况是,验证正在增长,而且现在非常复杂,它需要对数据库进行一些查询,等等。。。所以这门课程有很多责任
所以我想,我需要一个服务来处理“添加”和进行所有验证,并将此责任从课程类中移除。问题是,学生集合是课程的私人成员,因此我无法将学生添加到服务类的课程中
我认为解决这个问题的另一种方法是将相关实体(学生)添加到上下文(来自服务),但这会破坏我的存储库(因为我必须将DbContext公开)。如果我直接从服务类使用DbContext,那么存储库就没有意义了,不是吗
那么,我应该如何设计呢?或者我应该做些什么来解决这个问题?
任何建议都会很受欢迎
谢谢 这并不能直接回答您的问题,特别是与code first EF和所有这些相关的问题(不是我的专业领域)。但看起来你确实有一个设计问题 我是DDD(领域驱动设计)的忠实粉丝。您可能想问的一些问题包括:
- “AddStudents”真的应该是一种方法吗?对象应该有行为,而“添加学生”是一个数据持久性概念,而不是域/实体概念。也许行为会是“注册”?注册可能有自己的逻辑,因此对象可以封装该逻辑
- 第二,学生是否存在于他们所修课程的概念之外?例如,他们可以选修多种课程吗?那么这里的收藏可能不应该是私有的……是否应该有一个名为StudentEnrollment的新对象
无论如何,我建议不要公开您的DbContext 这并不能直接回答您的问题,特别是与code first EF和所有这些相关的问题(不是我的专业领域)。但看起来你确实有一个设计问题 我是DDD(领域驱动设计)的忠实粉丝。您可能想问的一些问题包括:
- “AddStudents”真的应该是一种方法吗?对象应该有行为,而“添加学生”是一个数据持久性概念,而不是域/实体概念。也许行为会是“注册”?注册可能有自己的逻辑,因此对象可以封装该逻辑
- 第二,学生是否存在于他们所修课程的概念之外?例如,他们可以选修多种课程吗?那么这里的收藏可能不应该是私有的……是否应该有一个名为StudentEnrollment的新对象
无论如何,我建议不要公开您的DbContext 我不同意实体中像
AddStudent(…)
这样的方法。让实体成为简单的数据传输对象——即POCO——进出EntityFramework。我更愿意让我的业务逻辑来处理这些事情
您可以将IdCourse
和Students
设置器设置为private。我见过其他人也使用受保护的。。。但是为什么呢?有实体的后代吗
Julie Lerman等人推荐的ICollection
属性的一种解决方案是:
private ICollection<Student> _students;
public virtual ICollection<Student> Students {
get; { _students ?? (_students = new Collection<Student>()); }
private set { _students = value; }
}
有几种不同的方法可以实现这一点,本示例还远未完成,但应该为您提供一个基本概念
基本的DbContext
(由CourseRepository
继承或封装)将跟踪课程
的更改以及学生
与课程
的新增学生或关系
至于使用私有或受保护的setter,我想限制它的使用
private ICollection<Student> _students;
public virtual ICollection<Student> Students {
get; { _students ?? (_students = new Collection<Student>()); }
private set { _students = value; }
}
// this is how I would approach a business layer method
void AddStudentToCourse(string CourseName, Student NewStudent) {
// may employ a using block for repository
// also validate student
using (var repo = new CourseRepository()) {
var course = repo.GetCourse(CourseName);
course.Students.Add(NewStudent);
repo.Save();
}
}