我不完全确定我想要的是否可能,这就是我想要的:
我正在存储一些不同的对象。我们假设Users
的集合和Projects
的集合。
以下是一些可能的示例:
public class User
{
public int UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string EmailAddress { get; set; }
public List<Project> Projects { get; set;}
}
public class Project
{
public int ProjectId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public User Manager { get; set; }
}
如您所见,用户可以有多个项目,而项目有用户。
基本上,当我存储这些内容时,我希望能够在用户集合中编辑用户,并自动更新任何包含该用户的项目以包含有关该用户的更新信息。随后,如果我更新项目,那么具有该项目的任何用户将自动更新其项目。就像某种存储对象的引用而不是值的方式一样?
有没有办法做到这一点?
答案 0 :(得分:3)
这里有你的对象引用。这意味着,只要您指的是相同的对象(实例),默认情况下一切都会按照您的预期运行。
示例(使用您的课程):
User u = new User();
Project p = new Project();
p.Manager = u;
u.Projects.Add(p);
这会创建一个空用户和一个空项目。项目引用用户,用户的项目列表引用项目。
现在您更改用户和项目的名称:
u.FirstName = "Test";
u.LastName = "User";
这将使您获得以下结果:
Console.WriteLine("{0} {1}", p.Manager.FirstName, p.Manager.LastName);
=> Test User
你现在可以做的另一件事是:
User userInfo = p.Manager;
userInfo.EMailAddress = "test@company.org";
这将反映您访问所分配的用户对象的任何方式,因为所有这些“变量”都“指向”同一对象实例(它们引用内存中的同一对象)。
您甚至可以将对象引用传递给另一种方法:
public void ChangeProjectManagerEmail(Project theProject, string newEMail)
{
theProject.Manager.EMailAddress = newEMail;
}
调用上面的方法:
ChangeProjectManagerEmail(p, "hello@world.com");
会导致这个:
Console.WriteLine(u.EMailAddress);
=> hello@world.com
不起作用:
User anotherUser = new User();
anotherUser.UserId = 5;
Console.WriteLine(p.Manager.UserId);
这将输出0
,因为新用户anotherUser
未被任何其他对象引用。
在坚持这样的结构时,你需要小心。存储它(在文件,数据库等中)非常简单,您需要确保在读取数据时重新创建完全相同的对象结构。想象一下:
首先,您需要决定是要保留每个用户还是每个项目,否则您可能会重复工作。当恢复持久性信息时,您需要确保只创建一个用户! (最好使用唯一ID来检查用户是否已经恢复)。否则,您最终会得到两个具有相同信息的不同User
个对象,您会想知道为什么更改用户仅反映一个项目。最糟糕的情况是,在更改用户信息后,您最终会得到两个具有相同ID但存储中信息不同的用户。
所有这一切:观看!在交叉引用方面,您的对象结构有些危险。就像现在一样,很有可能将一个项目添加到一个用户,该用户将一个完全不同的用户作为其管理者。例如:
User user1 = new User();
// Initialize ID, name, etc.
User user2 = new User();
// Initialize ID, name, etc.
Project p = new Project();
// Initialize stuff
p.Manager = user2;
user1.Projects.Add(p);
在这里查看问题?
答案 1 :(得分:0)
您可以实施观察者设计模式,以便在特定对象发生变化时通知“观察者”。
“观察者设计模式需要在注册通知的观察者与提供者之间进行划分,提供者监视数据并向一个或多个观察者发送通知。”
请参阅Dot Net中此模式的实现:
https://msdn.microsoft.com/en-us/library/ff506346(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/ee817669.aspx
如果只想要数据库级别,可以创建一个“ON UPDATE”触发器来进行所需的更改。
答案 2 :(得分:0)
为什么不在项目中保留用户ID,当您需要知道项目所属的人时,只需运行select
users.select(x => x.userid == project.userid)