2017-08-24 22 views
1

初始狀態的條目:EF 6:動態複製的DbSet

選擇多個條目複製:

var violations = entities.StagingViolation.Where(entry => entry.ViolationCode == processingEngineViolation.ViolationCode).ToList(); 

使用反射通過「StagingViolation」的屬性,迭代器對象和複製所有屬性。只有財產 「ProcessingId」(類型:GUID)應分配一個新的值:

entities.StagingViolation.AddRange(violations.Select(violation => { 
     var newViolation = new StagingViolation(); 

     typeof(StagingViolation).GetProperties() 
       .ToList() 
       .ForEach(property => { 
        typeof(StagingViolation).GetProperty(property.Name).SetValue(newViolation, property.GetValue(violation, null)); 
       }); 

     newViolation.ProcessingId = newProcessingId; 

     return newViolation; 
})); 

entities.SaveChanges(); 

假設StagingViolation類看起來是這樣的:

public class StagingViolation { 
    public Guid ProcessingId { get; set; } 
    public string ViolationCode { get; set; } 
    public string ViolationDetailCode { get; set; } 
} 

預期結果:

原件StagingViolation物件看起來像這樣:

ProcessingId = 'B4E3D49F-B8E3-4988-AAF2-42259059FA03' 
ViolationCode = 'ABC' 
ViolationDetailCode = 'ABC.123' 

複製StagingViolation應該是這樣的:

var newProcessingId = 'F8028E92-7234-4590-8EAB-170DE5B5E6DA' 

-------------------- 

ProcessingId = newProcessingId 
ViolationCode = 'ABC' 
ViolationDetailCode = 'ABC.123' 

但是複製的對象不包含相同的「ProcessingId」至於到底原始對象。有人知道爲什麼?

編輯1:

這整個功能包含在以下方面:

private void CopyViolations(OverrideCodeInput violationOverrideCode, Guid newProcessingId) { 
... 
} 

我經過反覆調試,並發現「newProcessingId」包含正確的值,並同時執行newViolation.ProcessingId = newProcessingId正確。但最終,當我在entities.SaveChanges處使用斷點時,集合確實添加了新條目,但它們包含舊的「ProcessingId」。

僅供參考:「ProcessingId」是主鍵的一部分。這就是爲什麼我在SaveChanges()遇到主鍵違規的例外。

+0

是'ProcessingId'定義爲關鍵?當你確切地看到舊值時,它是在「SaveChanges()」之後,還是在你設置之後立即出現?另外,在哪裏以及如何初始化'newProcessingId'? – haim770

+0

@ haim770我編輯了我的帖子。 – rbr94

+0

主鍵是如何生成的?你可以手動設置它的值,還是數據庫生成? – haim770

回答

1

由於IvanStoev和haim770的幫助,我通過將NavigationProperties複製到新對象中解決了我的問題。因此,我使用的檢查屬性類型擴展遍歷StagingViolation的屬性之前:property.PropertyType.IsSimpleType()

entities.StagingViolation.AddRange(violations.Select(violation => { 
     var newViolation = new StagingViolation(); 

     typeof(StagingViolation).GetProperties().Where(property => property.PropertyType.IsSimpleType()) 
        .ToList() 
        .ForEach(property => { 
         typeof(StagingViolation).GetProperty(property.Name).SetValue(newViolation, property.GetValue(violation, null)); 
    }); 

    newViolation.ProcessingId = newProcessingId; 

    return newViolation; 
})); 


public static class TypeExtension { 
    public static bool IsSimpleType(this Type type) { 
     while (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) { 
      type = type.GetGenericArguments()[0]; 
     } 

     return type.IsValueType || type.IsPrimitive || new[] { typeof(string), typeof(decimal), typeof(DateTime), typeof(DateTimeOffset), typeof(TimeSpan), typeof(Guid) }.Contains(type) || Convert.GetTypeCode(type) != TypeCode.Object;   
    } 
}