C# 在C语言中管理多对多关系#
我试图在应用程序级别以多对多关系管理一些简单的列表。每次在两个对象之间建立连接(例如C# 在C语言中管理多对多关系#,c#,asp.net,many-to-many,C#,Asp.net,Many To Many,我试图在应用程序级别以多对多关系管理一些简单的列表。每次在两个对象之间建立连接(例如teacher.AddStudent(),student.RemoveTeacher())时,我都会更新它们之间的关系 我知道如果我使用SQL,我会使用类似于StudentTeachertable的东西来管理关系,但我试图了解如何在应用程序中实现这一点 using System; using System.Collections.Generic; using System.Collections.ObjectMo
teacher.AddStudent()
,student.RemoveTeacher()
)时,我都会更新它们之间的关系
我知道如果我使用SQL,我会使用类似于StudentTeacher
table的东西来管理关系,但我试图了解如何在应用程序中实现这一点
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace StudentTeacher
{
// create simple interface
public interface IPerson {}
// abstract class
public abstract class Person : IPerson
{
public int Id { get; set; }
}
// concrete "Teacher"
public class Teacher : Person
{
// private list of student ids
private List<int> _studentIds { get; set; }
// readonly accessor
public ReadOnlyCollection<int> StudentIds {
get { return _studentIds.AsReadOnly(); }
}
// constructor
public Teacher(int id) {
Id = id;
_studentIds = new List<int>();
}
// add a student
public void AddStudent(Student student)
{
if (!_studentIds.Contains(student.Id)) {
_studentIds.Add(student.Id);
student.AddTeacher(this);
}
}
// remove a student
public void RemoveStudent(Student student)
{
if (_studentIds.Contains(student.Id)) {
_studentIds.Remove(student.Id);
student.RemoveTeacher(this);
}
}
public string ToString() {
return String.Format("Id:{0} | StudentIds:{1}", Id, String.Join(",", StudentIds));
}
}
/// concrete "Student"
public class Student : Person
{
// private list of teacher ids
private List<int> _teacherIds { get; set; }
// readonly accessor
public ReadOnlyCollection<int> TeacherIds {
get { return _teacherIds.AsReadOnly(); }
}
// constructor
public Student(int id) {
Id = id;
_teacherIds = new List<int>();
}
// add a teacher
public void AddTeacher(Teacher teacher)
{
if (!_teacherIds.Contains(teacher.Id)) {
_teacherIds.Add(teacher.Id);
teacher.AddStudent(this);
}
}
// remove teacher
public void RemoveTeacher(Teacher teacher)
{
if (_teacherIds.Contains(teacher.Id)) {
_teacherIds.Remove(teacher.Id);
teacher.RemoveStudent(this);
}
}
// simple override
public string ToString() {
return String.Format("Id:{0} | TeacherIds:{1}", Id, String.Join(",", TeacherIds));
}
}
class Program
{
static void Main(string[] args)
{
// create teachers
var teacher1 = new Teacher(101);
var teacher2 = new Teacher(102);
// create students
var student1 = new Student(501);
var student2 = new Student(502);
var student3 = new Student(503);
// create some relationships
teacher1.AddStudent(student1);
teacher1.AddStudent(student2);
teacher1.AddStudent(student3);
// see what's happening
Console.WriteLine(teacher1.ToString()); // "Id:101 | StudentIds:501,502,503"
Console.WriteLine(student1.ToString()); // "Id:501 | TeacherIds:101"
Console.WriteLine(student2.ToString()); // "Id:502 | TeacherIds:101"
Console.WriteLine(student3.ToString()); // "Id:503 | TeacherIds:101"
// update student1, student2
student1.AddTeacher(teacher2);
student2.AddTeacher(teacher2);
// -- Outputs
Console.WriteLine(student1.ToString()); // "Id:501 | TeacherIds:101,102"
Console.WriteLine(student2.ToString()); // "Id:502 | TeacherIds:101,102"
Console.ReadLine();
}
}
}
我有一种感觉,这会很快变得一团糟。我的问题是,
- 我是否应该添加静态观察者之类的东西,例如
并引发事件,例如。StudentTeacherObserver
,onteacheraded
李>OnStudentAdded
- 管理这种关系是否有特定的模式
- 是否有更适合此目的的数据结构,如果有,它是什么?我如何使用它
Teacher.Students[0].Teacher…
)通常会感到“凌乱”,尤其是在决定是延迟加载关系(闲聊)还是预先加载所有对象,然后映射引用(脂肪)时
不过我不认为你想得太多了。如果不对数据访问做出某种让步,则很难正确表示多对多。我认为您需要更深入地评估您的业务问题,以发现更具体的场景,从而确定是否需要更改任何内容。最简单的方法就是选择一个赢家。因此,不要同时实现这两种场景。下面是一个带有一点背景的链接: 你必须想出适合你的方法。用真实的物体来表示也不总是一个好主意。只需存储相关ID就足够了。在
订单
/订单项
至产品
示例中。可能没有理由在OrderItem
中包含实际的Product
对象,因为它不是Order
聚合的一部分。您仅使用产品
中的数据,之后它在订单项
上变为非规范化状态。在执行订单
之前(实际上有人开始填写订单
),可以对其进行更改。当然,关于停止流程(取消订单)和退回产品等的业务规则可能很复杂,但随着情况/业务的变化而变化
关键是尝试“剪切”对象图,以便清晰地定义聚合
这有助于延迟加载位。我从不使用惰性加载,我会敦促我遇到的任何人尽最大努力避免它。这个想法实际上不是要查询对象/域模型,而是另一种讨论
我希望这是有意义的:)有什么特别的原因让你不想让一个成熟的ORM为你处理所有这些吗?@SimonWhitehead,因为我想学习如何为自己做这件事。为什么事情会变得一团糟?这里唯一的混乱就是你现在所拥有的,它被很好地控制和封装。你预见到了什么样的问题?通过让你的类变得可观察(正如你在问题中所建议的),你将增加一堆不必要的复杂性。@YoryeNathan/caesay也许我想得太多了。这确实有效,但我想我是在问,这种方法有什么缺陷吗?
if (!_studentIds.Contains(student.Id)) {
_studentIds.Add(student.Id);
student.AddTeacher(this); // calling this directly feels bad
}