如何使用来自不同datacontexts的对象处理提交?

时间:2009-03-25 11:30:49

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

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

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

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

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将抛出异常,因为datacontext不会识别Person对象(即使它的类型相同)。你能做些什么来解决这个问题?

2 个答案:

答案 0 :(得分:2)

为什么开始使用两个不同的DataContexts?这听起来像个坏主意。为什么不给CarRepository传递DataContext的构造函数?然后两个存储库都可以使用相同的DataContext

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

答案 1 :(得分:1)

Linq2sql不支持直接使用跨datacontext对象-serialize / deserialize / attach真的不值得。

您拥有的方案是存储库之间耦合的结果。您正在使用相同的datacontext类创建内部依赖关系,该类在RegisterOwner代码上显示,尝试直接使用接收到的实体。

如果调用代码更新了person实体上的内容,如果RegisterOwner的代码真的保存了这些更改,请考虑会发生什么?

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

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

对于更加耦合的场景,您可以使用Jon的答案 - 为它们提供相同的DataContext实例。