1

在使用对象和接口时,写入数据库的最佳实践是什么?关于对象设计有很多意见,但我不清楚数据库端。一个简单的例子:

假设一个 Contact 基类包含常用字段,例如联系人姓名(Bill、Fred、Sally)和位置(家庭、工作等)。添加一个 IPhone 接口(区号、电话号码、分机)和一个 IEmail 接口(电子邮件地址,cc)以抽象出差异。然后创建继承自这些的类(电话、电子邮件),如下所示:

    电话:联系方式,IPhone
    电子邮件:联系方式,IEMail

另一种方法是创建一个 IContact 接口而不是 Contact 基类,如下所示:

    电话:IContact、iPhone
    电子邮件: IContact、IEMail

如果这些对象被写入单个数据库表,那么没有实现 NHibernate 或实体框架,那么数据访问代码的最佳实践是什么?我所看到的似乎相当笨拙。

4

5 回答 5

3

根据我的经验,当涉及到数据库时,如果您想要获得任何表面上的性能,则必须首先考虑良好的关系设计。之后,我的模型就很简单了:一张桌子,一个班级。如果我有自引用关系,我会创建另一个直接从原始类派生的类。连接被定义为对象列表(例如,订单有一个订单详细信息列表)。

完成此操作后,我将使用能够反映这些类并动态生成所需 SQL 的 DAL;分析后,我可能必须创建一些 SP,但其结果也会发送到接收 DTO。

到目前为止,我还没有遇到任何使用接口的理由。

于 2009-01-01T01:19:28.467 回答
1

听起来您要建模的是电话联系人和电子邮件联系人,但我认为您真正拥有的是具有主要联系方式的联系人:电话或电子邮件。我构建它的方式是组合——假设您希望灵活地拥有多个电话号码/电子邮件。如果每个人都可以使用一个,则可以将其直接存储在联系人表中。如果您需要多个地址,则使用与电话/电子邮件相同的方式处理它,并使用单独的表格。

联系人表
     联系人 ID
     名
     姓
     心肌梗死
     街道地址1
     街道地址2
     城市
     州省
     邮政编码
     PreferredContactMethod(0 = 电话,1 = 电子邮件)
     ... 更多细节 ...

电话号码表
     电话号码
     联系人 ID
     电话号码
     是主要的
     ...更多细节...

电子邮件地址表
     电子邮件ID
     联系人 ID
     电子邮件地址
     是主要的
     ...更多细节...

那么对于您的类,您将有一个 Contact 类,其中包含一个或多个 PhoneNumbers 和一个或多个 EmailAddresses。如果除了联系人以外,您还有其他东西有电话号码或电子邮件地址,那么让界面指示它们是 IPhoneable 或 IEmailable 可能是有意义的——这意味着您可以从中添加/删除电话号码或电子邮件地址,就像这样:

public interface IPhoneable
{
     public PhoneNumber GetPrimaryNumber();
     public void AddNumber( PhoneNUmber number );
     public IEnumerable<PhoneNumber> GetNumbers();
}

public interface IEmailable
{
     public EmailAddress GetPrimaryAddress();
     public void AddEmailAddress( EmailAddress address );
     public IEnumerable<EmailAddress> GetEmailAddresses();
}

public class Contact : IPhoneable, IEmailable
{
     private List<PhoneNumber> phoneNumbers;
     private List<EmailAddresses> emailAddresses;

     public int ContactID { get; private set; }
     public string FirstName { get; set; }
     ...

     public Contact()
     {
         this.phoneNumbers = new List<PhoneNumber>();
         this.emailAddresses = new List<EmailAddress>();
     }

     public PhoneNumber GetPrimaryNumber()
     {
          foreach (PhoneNumber number in this.phoneNumbers)
          {
               if (number.IsPrimary)
               {
                    return number;
               }
          }
          return null;
      }

      ...
}

如果你愿意,你可以有一个 PhoneableContact 和一个 EmailableContact ,它们可以从 Contact 子类化,并且可以根据首选的联系方法进行区分,但我真的不认为有必要这样做。如果你这样做了,那么 Contact 将不会实现任何一个接口——子类将分别实现适当的接口。

于 2009-01-01T05:02:38.440 回答
1

我想你需要考虑这三个实体之间的关系。大声说出以下陈述,看看哪些陈述对您的应用程序是正确的:

  • Phone 一个Contact
  • Phone 一个Contact

就您在此处发布的内容而言,听起来您可以通过使用第二个选项来大大降低应用程序的复杂性。

但是,您想知道数据访问,并且您提到有一个单一的数据库表,这让我想知道为什么您需要单独的实体Contact,PhoneEmail. 我建议您重构代码以包含单个实体来表示您的数据模型,因为这将降低代码库的复杂性,或者重构您的数据库模式以反映您真正想要的内容(基于您的示例代码)。

于 2009-01-01T01:21:45.407 回答
1

首先构建您的数据库,这样您就可以确定您实际上可以存储您需要的所有内容。然后构建常见查询,例如“所有客户及其主要电话号码”和“单个客户及其所有电话号码”。

这将暴露出明显的问题,例如没有足够的电话号码字段或无法指示真实电话号码。

您的数据库的使用时间至少是您的应用程序的三倍,并且很难更改,因此请确保从一开始就正确使用它。

于 2009-01-01T02:46:42.910 回答
0

在这种情况下......我认为最好的选择是使用数据库对象,如 DB4O。

“Db4o 是开放源代码对象数据库,它使 Java 和 .NET 开发人员能够存储和检索任何应用程序对象,包括主题图,只需一行代码,无需预定义或维护单独的、严格的数据模型。”

http://www.db4o.com/

于 2009-01-01T11:28:17.617 回答