我的程序比较复杂,但基本上问题就是这样 - 有表Customer和table City。在Customor中我有字段cityId和外键。
现在我可以编写这样的代码
customer.cityIdCity = myCity;
或
customer.cityId = 7;
问题是我不能使用第一种形式,因为城市被缓存,在这种情况下,数据将被当前数据上下文“劫持”(并且会发生异常),所以我更喜欢使用第二种形式。但是,当我为客户提交更改时,我会对数据中的不一致情况进行例外处理 - 这说实话 - cityId为7,但cityIdCity为空。
问题是 - 对于第二种形式,如何强制LINQ专注于id(并使用id执行简单插入),并接受丢失的对象。
字段cityId只是一个int(如表中所示),但是sqlmetal还为映射类cityIdCity创建了另一个属性,该类引用了City类(来自表City)。
在内部看起来像这样:
private EntityRef<City> _cityIdCity;
还有一个长属性cityIdCity,用于设置上述字段并处理事件触发以更改和更改字段的状态。
常规字段(int)的定义如下:
private System.Nullable<int> _cityId;
加上类似的财产。
我发现这是由于获取数据。加载数据后(在这种情况下为客户提供城市对象),Linq To SQL假定它是固定,即id和city引用必须同步。如果在更改它们之前没有读取它们就可以了,因为L2S设置了新值,但也可以在运行中从DB中获取新数据。
在更改之前我必须阅读客户的城市。
步骤如下:
因此在(3)中读取了客户的城市字段,在(7)中,要么抱怨使用来自其他上下文的数据,要么是不同步的字段(数据更改时的情况)。
为了进行比较,我使用Entity Framework测试了几个案例,它表现得更直接,即两种方法都没有问题(当用整个对象或只是id更改引用字段时)。
这是简化的代码,但显示了问题。
using (var Db = new L2S.DataClasses1DataContext())
{
var customer = Db.Customers.Single(it => it.cust_Id==2);
customer.Name = "New name";
Console.WriteLine(customer.City.city_Name); // loading city from DB
// cannot change, because we would be out of sync with referenced object
customer.city_Id = 57834;
Db.SubmitChanges();
}
使用与Pleun相同的示例。这是胖DC:
using (var Db = new L2S.DataClasses1DataContext())
{
...
customer.City = Db.Cities.Single (i=> i.id = 57834 );
Db.SubmitChanges();
}
因为您可以看到客户使用与城市相同的DC(城市被缓存!)。这是错误的,因为来自客户的每个格式错误的数据都会蔓延到DC(缓存)。因此,一小时前的错误现在也将出现。
这是很薄的DC:
var city = CacheDb.Cities.Single (i=> i.id = 57834 );
...
using (var Db = new L2S.DataClasses1DataContext())
{
...
customer.City = city;
Db.SubmitChanges();
}
然而,这不起作用,因为L2S不允许在DC之间共享实体(在典型情况下,在缓存和工作之间 - 更新 - DC)。
答案 0 :(得分:0)
你试过吗
using (var Db = new L2S.DataClasses1DataContext())
{
...
// leave out customer.city_Id = 57834; but replace with
customer.City = Db.Cities.Single (i=> i.id = 57834 );
Db.SubmitChanges();
}