我遇到了一个问题,即使用两个相同类型的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对象(即使它的类型相同)。你能做些什么来解决这个问题?
答案 0 :(得分:2)
为什么开始使用两个不同的DataContexts
?这听起来像个坏主意。为什么不给CarRepository
传递DataContext
的构造函数?然后两个存储库都可以使用相同的DataContext
。
使用单个DataContext
意味着提交可以作为一个事务进行,并且您不会遇到奇怪的问题,即上下文中的缓存对数据库中的内容有不同的想法。
答案 1 :(得分:1)
Linq2sql不支持直接使用跨datacontext对象-serialize / deserialize / attach真的不值得。
您拥有的方案是存储库之间耦合的结果。您正在使用相同的datacontext类创建内部依赖关系,该类在RegisterOwner代码上显示,尝试直接使用接收到的实体。
如果调用代码更新了person实体上的内容,如果RegisterOwner的代码真的保存了这些更改,请考虑会发生什么?
在相同的有界上下文中,存储库级别的这种类型的耦合可能是正常的。如果这些应该是独立的子系统,汽车存储库将专注于仅保存它要处理的信息,这是识别汽车系统中用户的所有者信息的子集。这是允许您沿途切换件的原因。当然,在您希望获得更高分离度的更复杂场景中,这更有意义。
请注意,在发布的示例中,您并不需要更新Person上的任何内容,因此您可以有效地使用仅在车主信息上设置人员ID的版本,而不是将其分配给完整的Person实例。 / p>
对于更加耦合的场景,您可以使用Jon的答案 - 为它们提供相同的DataContext实例。