gpt4 book ai didi

nhibernate - 有关资源库及其域对象的Save方法的问题

转载 作者:行者123 更新时间:2023-12-03 22:26:38 24 4
gpt4 key购买 nike

关于DDD,存储库模式和ORM,我有一个荒谬的问题。在此示例中,我有3个类:地址公司人员。一个人是公司的成员,并且有一个地址。公司也有一个地址。

这些类反射(reflect)数据库模型。我删除了模型的所有依赖项,因此它们不依赖于特定的ORM库,例如NHibernate或LinqToSql。这些依赖项在存储库内部处理。

存储库的一个内部,有一个 SavePerson(Person person)方法,会根据数据库中是否已经存在插入/更新 a Person。

由于Person对象有一个Company,因此在进行SavePerson调用时,我目前还保存/更新了Company属性的值。在此过程中,我会插入/更新公司的所有数据-名称和地址。

但是,我真的很难考虑这样的情况:在与人打交道时公司的数据可能会发生变化-我只希望能够将公司分配给人,或者将人转移到另一个公司。我不认为我想和一个新的人一起创建一个新的公司。因此,SaveCompany调用会引入不必要的数据库调用。保存人员时,我应该只能更新CompanyId列。

但是由于Person类具有Company属性,因此我倾向于使用它来更新/插入它。从严格/纯粹的角度来看,SavePerson方法应该保存整个Person。

首选方式是什么?在保存人员或保存其所有数据时只是插入/更新Company属性的CompanyId?还是为两种情况都创建两种不同的方法(您将如何命名?)

另外,另一个问题是,我目前有保存人,地址和公司的独特方法,因此当保存公司时,我也称为SaveAddress。假设我使用LinqToSql-这意味着我不会在同一Linq查询中插入/更新公司和地址。我猜有2个选择调用(检查公司是否存在,地址是否存在)。然后两个都需要两次插入/更新。如果引入更多复合模型类,则更多。 LinqToSql是否有一种方法可以优化这些调用?

public class Address
{
public int AddressId { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
}

public class Company
{
public int CompanyId { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
}


public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public Company Company { get; set; }
public Address Address { get; set; }

}

编辑

另请参见this follow up question。值(value)对象如何存储在数据库中?

最佳答案

我本人最近使用了Keith建议的IRepository方法。但是,您不应在此关注该模式。相反,DDD剧本中还有其他几篇文章可以在此处应用。

为您的地址使用值对象

首先,这里有值对象(VO)的概念,您可以在此处应用。在您的情况下,它将是地址。值对象和实体对象之间的区别在于,实体具有标识;即,实体具有标识。 VO不这样做。 VO的身份实际上是其属性的总和,而不是唯一身份。在书Domain-Drive Design Quickly(也是免费的PDF下载)中,他很好地解释了这一点,他指出,地址实际上只是地球上的一个点,不需要像人一样的单独的类似于社会保障的身份。地球上的这一点是街道,数字,城市, zip 和国家/地区的组合。它可以具有经度和纬度值,但按​​照定义,它们仍然是VO,因为它是两点的组合。

使用服务将您的实体合并为一个实体以对其进行操作。

另外,不要忘记DDD手册中的“服务”概念。在您的示例中,该服务将是:

public class PersonCompanyService
{
void SavePersonCompany(IPersonCompany personCompany)
{
personRepository.SavePerson();
// do some work for a new company, etc.
companyRepository.SaveCompany();
}
}

当您有两个需要同时执行相似操作以协调其他操作组合的实体时,就需要一种服务。在您的情况下,保存一个Person()并同时创建一个空白的Company()。

ORM惯常要求一个身份,期限。

现在,您将如何将地址VO保存在数据库中?您显然会使用IAddressRepository。但是由于大多数ORM(即LingToSql)都要求所有对象都具有一个Identity,所以要诀窍:将身份标记为模型中的内部对象,这样就不会在Model层之外显示该身份。这是史蒂文·桑德森(Steven Sanderson)自己的建议。
public class Address
{
// make your identity internal
[Column(IsPrimaryKey = true
, IsDbGenerated = true
, AutoSync = AutoSync.OnInsert)]
internal int AddressID { get; set; }

// everything else public
[Column]
public string StreetNumber { get; set; }
[Column]
public string Street { get; set; }
[Column]
public string City { get; set; }
...
}

关于nhibernate - 有关资源库及其域对象的Save方法的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/672836/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com