【问题标题】:How do I handle submits using objects from different datacontexts?如何使用来自不同数据上下文的对象处理提交?
【发布时间】:2009-05-02 10:08:06
【问题描述】:

我遇到了一个问题,即使用来自两个相同类型的数据上下文的对象,不会提交对象。为简单起见,请考虑以下 LINQ-to-SQL 设计,其中我们有描述汽车和人员的数据库表。

+--------------+         +--------+
| Car          | 1     1 | Person |
+--------------+---------+--------+
| Registration |         | name   |
| ownerId {FK} |         +--------+
+--------------+

然后我们有两个数据存储库,它们具有相同数据上下文类的实例,具有以下方法:

public OwnerRepository {
    private MyDataContext db;

    public Person GetOwnerByName(string ownerName)
    {
        return (from person in db.Persons
               where person.Name == ownerName
               select person).SingleOrDefault();
    }
}

public CarRepository {
    private MyDataContext db;

    public Car GetCarByRegistration(string registration)
    {
        return (from car in db.Cars 
               where car.Registration == registration
               select car).SingleOrDefault();
    }

    public void RegisterOwner(Person owner, string registration)
    {
        var car = GetCarByRegistration(registration);
        car.Owner = owner;
        db.SubmitChanges();
    }
}

假设我们从 OwnerRepository 中获取一个 Person 并使用它来将该人注册为汽车的所有者:

var owner = ownerRepository.GetOwnerByName("Peter Pan");
carRepository.RegisterOwner(owner, "TOO COOL");

RegisterOwner 方法将抛出异常,因为数据上下文无法识别 Person 对象(即使它属于同一类型)。你能做些什么来解决这个问题?

【问题讨论】:

    标签: c# .net linq-to-sql


    【解决方案1】:

    为什么要从两个不同的DataContexts 开始?这听起来是个坏主意。为什么不给CarRepository 一个你传入DataContext 的构造函数呢?然后两个存储库可以使用相同的DataContext

    使用单个 DataContext 意味着提交可以作为一个事务进行,并且您不会遇到奇怪的问题,即上下文中的缓存对数据库中的内容有不同的想法。

    【讨论】:

    • 是的,这只是一个例子。我确实有可以将数据上下文作为“ACTUAL”存储库类中的参数的构造函数。看起来我需要一个构建器类,它可以构建具有相同数据上下文的所有存储库。
    • 对 - 我很确定这是正确的解决方案。混合和匹配来自不同上下文的对象对我来说听起来很糟糕。
    • 大多数使用这种分解的人倾向于使用 IOC 容器,它基本上会为您处理“构建器”部分(例如 NInject、Castle Windsor、Spring .NET、Unity.. .)
    • Jon Skeet:开箱即用地混合和匹配不同上下文中的对象实际上是行不通的。我希望有人知道如何将一个对象从一个上下文附加到另一个上下文中。 :)
    • Denis Troller:以前从未使用过 IOC Containers,但我现在似乎遇到了实际用途。感谢您的提示。
    【解决方案2】:

    Linq2sql 不支持直接使用跨数据上下文对象 -serialize/deserialize/attach 真的不值得。

    您所拥有的场景是存储库之间耦合的结果。您正在使用相同的 datacontext 类创建对它的内部依赖,这在 RegisterOwner 代码中显示,尝试直接使用接收到的实体。

    考虑如果调用代码更新了个人实体上的某些内容会发生什么,RegisterOwner 的代码真的应该保存这些更改吗?

    存储库级别的这种类型的耦合在相同的有界上下文中可能没问题。如果这些应该是独立子系统的片段,那么汽车存储库将专注于仅保存它要处理的信息,这是在汽车系统中识别用户的所有者信息的子集。这就是允许您沿途切换片段的原因。当然,这在您想要更高程度的分离的更复杂的场景中更有意义。

    请注意,在发布的示例中,您实际上不需要更新 Person 上的任何内容,因此您可以有效地使用仅在车主信息上设置人员 ID 的版本,而不是为其分配完整的 Person 实例。

    对于更耦合的场景,您可以使用 Jon 的答案 - 给他们相同的 DataContext 实例。

    【讨论】:

      猜你喜欢
      • 2020-12-15
      • 1970-01-01
      • 2015-05-22
      • 1970-01-01
      • 2011-02-21
      • 1970-01-01
      • 2019-07-12
      • 1970-01-01
      • 2019-06-02
      相关资源
      最近更新 更多