Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.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

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
.net 实体框架:具有关系等的对象设计_.net_Entity Framework_Object Design - Fatal编程技术网

.net 实体框架:具有关系等的对象设计

.net 实体框架:具有关系等的对象设计,.net,entity-framework,object-design,.net,Entity Framework,Object Design,我有一个关于大学管理的.net解决方案(使用实体框架,使用CodeFirst方法)。项目的架构如下所示: 数据访问(DbContext和通用存储库) 实体(代码优先类) 服务(服务类别) Web(一个MVC项目,解释起来并不重要) 为了使问题更简单,我将只讨论我的领域中的两个类(在实体层上): 课程 学生 这门课可以有很多学生。解决方案的目标是将学生添加到课程中(中间有一些验证) 课程.cs 公共课 { [关键] public int IdCourse{get;protected set

我有一个关于大学管理的.net解决方案(使用实体框架,使用CodeFirst方法)。项目的架构如下所示:

  • 数据访问(DbContext和通用存储库)
  • 实体(代码优先类)
  • 服务(服务类别)
  • Web(一个MVC项目,解释起来并不重要)
为了使问题更简单,我将只讨论我的领域中的两个类(在实体层上):

  • 课程
  • 学生
这门课可以有很多学生。解决方案的目标是将学生添加到课程中(中间有一些验证)

课程.cs

公共课
{
[关键]
public int IdCourse{get;protected set;}
公共字符串名称{get;set;}
公共虚拟ICollection学生{get;protected set;}
公立学校学生(学生)
{
//一些验证
学生。添加(学生);
}
}
如您所见,该类具有用于将学生添加到课程的属性。 目前的情况是,验证正在增长,而且现在非常复杂,它需要对数据库进行一些查询,等等。。。所以这门课程有很多责任

所以我想,我需要一个服务来处理“添加”和进行所有验证,并将此责任从课程类中移除。问题是,学生集合课程的私人成员,因此我无法将学生添加到服务类的课程中

我认为解决这个问题的另一种方法是将相关实体(学生)添加到上下文(来自服务),但这会破坏我的存储库(因为我必须将DbContext公开)。如果我直接从服务类使用DbContext,那么存储库就没有意义了,不是吗

那么,我应该如何设计呢?或者我应该做些什么来解决这个问题? 任何建议都会很受欢迎


谢谢

这并不能直接回答您的问题,特别是与code first EF和所有这些相关的问题(不是我的专业领域)。但看起来你确实有一个设计问题

我是DDD(领域驱动设计)的忠实粉丝。您可能想问的一些问题包括:

  • “AddStudents”真的应该是一种方法吗?对象应该有行为,而“添加学生”是一个数据持久性概念,而不是域/实体概念。也许行为会是“注册”?注册可能有自己的逻辑,因此对象可以封装该逻辑
  • 第二,学生是否存在于他们所修课程的概念之外?例如,他们可以选修多种课程吗?那么这里的收藏可能不应该是私有的……是否应该有一个名为StudentEnrollment的新对象
还有其他问题,但一定要从整体上看待您的问题和对象的设计方式。添加一个学生的课程是否与向该学生添加课程相同

也许您的服务可以进行验证,或者将学生添加到课程中,或者将课程添加到学生中(或者两者都添加),并将其保存在自己的存储库中

无论如何,我推荐Julie Lerman的DDD系列,面向面向数据的EF人员:


无论如何,我建议不要公开您的DbContext

这并不能直接回答您的问题,特别是与code first EF和所有这些相关的问题(不是我的专业领域)。但看起来你确实有一个设计问题

我是DDD(领域驱动设计)的忠实粉丝。您可能想问的一些问题包括:

  • “AddStudents”真的应该是一种方法吗?对象应该有行为,而“添加学生”是一个数据持久性概念,而不是域/实体概念。也许行为会是“注册”?注册可能有自己的逻辑,因此对象可以封装该逻辑
  • 第二,学生是否存在于他们所修课程的概念之外?例如,他们可以选修多种课程吗?那么这里的收藏可能不应该是私有的……是否应该有一个名为StudentEnrollment的新对象
还有其他问题,但一定要从整体上看待您的问题和对象的设计方式。添加一个学生的课程是否与向该学生添加课程相同

也许您的服务可以进行验证,或者将学生添加到课程中,或者将课程添加到学生中(或者两者都添加),并将其保存在自己的存储库中

无论如何,我推荐Julie Lerman的DDD系列,面向面向数据的EF人员:


无论如何,我建议不要公开您的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();
       }
   }