2017-08-24 4 views
1

のエントリコピー:EF 6:動的初期状況DbSet

をコピーするためのいくつかのエントリを選択します。「StagingViolation」オブジェクトとコピーのプロパティを通じてイテレータする

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

使用反射をすべてのプロパティ。専用のプロパティ "ProcessingId"(タイプ:GUID)が新しい値を割り当てる必要があります:

StagingViolationクラスは次のようになりますと仮定すると、
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(); 

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' 

は次のようになります。

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

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

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

しかし、コピーされたオブジェクトは、最終的には元のオブジェクトと同じ「ProcessingId」を含んでいます。なぜ誰かが知っていますか?

EDIT 1:この全体の機能は次のコンテキストに含まれる

:私は反復を通じてデバッグ及び「newProcessingId」が正しい値が含まれていることが判明し、newViolation.ProcessingId = newProcessingIdも実行された

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

正しくしかし最後に、私がentities.SaveChangesにブレークポイントを使用すると、コレクションは実際に新しいエントリを追加しましたが、古い "ProcessingId"を含んでいます。

FYI: "ProcessingId"は主キーの一部です。だから、私はSaveChanges()で主キーの違反に例外が発生します。

+0

property.PropertyType.IsSimpleType()は 'ProcessingId'は、キーとして定義されていますか?正確に古い値を見ると、 'SaveChanges()'の後か、それともすぐに設定したのでしょうか?また、 'newProcessingId'はどこでどのように初期化されていますか? – haim770

+0

@ haim770私は自分の投稿を編集しました。 – rbr94

+0

主キーはどのように生成されますか?手動でその値を設定することはできますか、それともデータベースで生成されますか? – haim770

答えて

1

IvanStoevとhaim770の助けを借りて、NavigationPropertiesが新しいオブジェクトにコピーされないようにして問題を解決しました。したがって、私はStagingViolationのプロパティを反復処理する前PropertyTypeはをチェックするための拡張機能を使用します。

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;   
    } 
} 
関連する問題