|
1 | | -// Copyright (C) 2003-2010 Xtensive LLC. |
2 | | -// All rights reserved. |
3 | | -// For conditions of distribution and use, see license. |
| 1 | +// Copyright (C) 2007-2020 Xtensive LLC. |
| 2 | +// This code is distributed under MIT license terms. |
| 3 | +// See the License.txt file in the project root for more information. |
4 | 4 | // Created by: Dmitri Maximov |
5 | 5 | // Created: 2007.08.03 |
6 | 6 |
|
@@ -273,32 +273,57 @@ protected internal Key GetReferenceKey(FieldInfo field) |
273 | 273 |
|
274 | 274 | protected internal void SetReferenceKey(FieldInfo field, Key value) |
275 | 275 | { |
| 276 | + if (Session.StorageNodeId != value.NodeId) { |
| 277 | + throw new ArgumentException(Strings.ExKeyBelongsToDifferentStorageNode, "value"); |
| 278 | + } |
| 279 | + |
| 280 | + // KeyRemapper also uses this method during persist so we need to detect whether it is KeyRemapper |
| 281 | + var isPersisting = Session.IsPersisting; |
276 | 282 | Key oldValue = null; |
277 | 283 | try { |
278 | 284 | oldValue = GetReferenceKey(field); |
279 | | - if (field.ReflectedType.IsInterface) |
| 285 | + if (field.ReflectedType.IsInterface) { |
280 | 286 | field = TypeInfo.FieldMap[field]; |
| 287 | + } |
| 288 | + |
281 | 289 | SystemBeforeSetValue(field, value); |
282 | | - if (!field.IsEntity) |
| 290 | + if (!field.IsEntity) { |
283 | 291 | throw new InvalidOperationException( |
284 | | - String.Format(Strings.ExFieldIsNotAnEntityField, field.Name, field.ReflectedType.Name)); |
| 292 | + string.Format(Strings.ExFieldIsNotAnEntityField, field.Name, field.ReflectedType.Name)); |
| 293 | + } |
| 294 | + |
| 295 | + if (!isPersisting) { SystemBeforeTupleChange(); } |
285 | 296 |
|
286 | 297 | var types = Session.Domain.Model.Types; |
287 | 298 | if (value == null) { |
288 | | - for (int i = 0; i < field.MappingInfo.Length; i++) |
| 299 | + for (var i = 0; i < field.MappingInfo.Length; i++) { |
289 | 300 | Tuple.SetValue(field.MappingInfo.Offset + i, null); |
| 301 | + } |
| 302 | + |
| 303 | + if (!isPersisting) { SystemTupleChange(); } |
290 | 304 | return; |
291 | 305 | } |
292 | | - if (!field.ValueType.IsAssignableFrom(value.TypeInfo.UnderlyingType)) |
| 306 | + if (!field.ValueType.IsAssignableFrom(value.TypeInfo.UnderlyingType)) { |
293 | 307 | throw new InvalidOperationException(string.Format("Key of {0} type is not assignable to field of {1} type", value.TypeInfo.Name, field.ValueType.Name)); |
| 308 | + } |
| 309 | + |
| 310 | + if (value == oldValue) { |
| 311 | + return; |
| 312 | + } |
294 | 313 |
|
295 | 314 | value.Value.CopyTo(Tuple, 0, field.MappingInfo.Offset, field.MappingInfo.Length); |
296 | | - if (field.IsPrimaryKey) |
297 | | - value.Value.CopyTo(((Entity)this).Key.Value, 0, field.MappingInfo.Offset, field.MappingInfo.Length); |
| 315 | + if (field.IsPrimaryKey) { |
| 316 | + value.Value.CopyTo(((Entity) this).Key.Value, 0, field.MappingInfo.Offset, field.MappingInfo.Length); |
| 317 | + } |
| 318 | + |
| 319 | + if (!isPersisting) { |
| 320 | + SystemTupleChange(); |
| 321 | + } |
| 322 | + |
298 | 323 | SystemSetValue(field, oldValue, value); |
299 | 324 | SystemSetValueCompleted(field, oldValue, value, null); |
300 | 325 | } |
301 | | - catch(Exception e) { |
| 326 | + catch (Exception e) { |
302 | 327 | SystemSetValueCompleted(field, oldValue, value, e); |
303 | 328 | throw; |
304 | 329 | } |
|
0 commit comments