以下是我需要创建的不同类的设置:
Author – AuthorId, AuthorName, DateOfBirth, State, City, Phone.
Publisher – PublisherId, PublisherName, DateOfBirth, State, City, Phone.
Category – CategoryId, CategoryName, Description.
Book – BookId, Category, Title, Author, Publisher, Description, Price, ISBN, PublicationDate.
现在您可以看到作者在Book和AuthorId中的作者类是一样的。如何在C#中实现这一点
答案 0 :(得分:5)
您的Book
对象可能会引用该类中的Author
,如下所示。
public class Author
{
public int AuthorId { get; set; }
public string AuthorName { get; set; }
}
public class Book
{
private Author _author { get; set; }
public Book(Author author)
{
_author = author;
}
public void PrintBookAuthor()
{
Console.WriteLine(_author.AuthorName);
}
}
然后设置:
Author author = new Author();
author.AuthorName = "Darren Davies";
Book programmingBook = new Book(author);
programmingBook.PrintBookAuthor();
答案 1 :(得分:2)
首先,您需要将关系设计与面向对象设计区分开来。
面向对象的编程(从现在开始只是 OOP )不是关系型的,而是层次结构,因此,那里有没有外键的概念。
此外,在OOP中,对象之间存在两种关系:
A
和B
,并且您可以说B
是A
,那么您需要使用继承 。例如,Cat
为Animal
。A
和B
,并且您可以说A
一个B
,那么您需要使用组合物。例如,Car
有一个Wheel
。现在采用这些规则并尝试将它们应用于您的特定情况:
Book
Author
。答对了!您需要使用组合。通过声明由封闭类型拥有的类的属性来表达组合。
在你的情况下:
public class Book
{
public Author Author { get; set; }
}
以下代码示例错误:
public class Book
{
public int AuthorId { get; set; }
}
...因为OOP 是分层,因此,您不会搜索与Book
相关联的作者,但是您将Book
遍历到获取Author
的信息。
换句话说,在OOP中,外键是关联对象的对象引用。
如果您希望获得给定Author
的{{1}},请在OOP中查看如何以正确方式执行操作的摘要:
Book
现在让我们看一下错误的示例:
BookRepository bookRepo = new BookRepository();
Book book = bookRepo.GetById(302);
Author author = book.Author;
你不觉得最后错误的样本在OOP世界中并不自然吗?为什么需要执行其他查询来获取整个BookRepository bookRepo = new BookRepository();
Book book = bookRepo.GetById(302);
AuthorRepository authorRepo = new AuthorRepository();
Author author = authorRepo.GetById(book.AuthorId);
对象?这感觉非常关系!
另一方面,将唯一标识符与Author
或任何对象相关联并没有错,因为您需要将每个标识符与其他标识符进行唯一区分,此外还有基础数据存储空间可能是关系型的,可能需要根据主键 / 外键来存储和检索对象。
如果我只想让图书对象只能访问authorid,该怎么办? 没有别的。因为通过这种方法,我能够访问所有 作者的要素。
欢迎来到 interfaces 的世界。其中一个用例是发布信息。或者,换句话说,只发布您要发布的内容:
Author
现在您只需将public interface IUniquelyIdentifiable
{
int Id { get; set; }
}
public class Author : IUniquelyIdentifiable
{
public int Id { get; set; }
// ...and the rest of properties
}
与IUniquelyIdentifiable
关联,而不是Book
:
Author
...您仍然可以在public class Book
{
public IUniquelyIdentifiable Author { get; set; }
}
上设置完整的Author
:
Book
这将隐藏除Book book = new Book();
book.Author = new Author();
之外的所有内容,而在代码的某些部分,您可以Author.Id
投放到IUniquelyIdentifiable
:
Author
如果您要使用OR/M,则需要谨慎,因为将对象模型映射到目标关系模型可能更难。
恕我直言,作为一般规则,我不会隐藏可以持久化的对象的对象属性(即那些可以保存到数据库中的对象)。