2011-11-23 9 views
7

Tôi nghĩ rằng tôi thiếu một khái niệm đơn giản với giá trị và/hoặc AutoMapper, nhưng làm thế nào để bạn sao chép sâu một phụ huynh dto.Entity để biz.Entity và bao gồm tất cả trẻ em?omu.valueinjecter bản sao sâu không giống như các loại

Ví dụ: biz.person.InjectFrom(dto.person). Tôi muốn bộ sưu tập dto.person.AddressList sao chép xuống bộ sưu tập biz.person.AddressList, mặc dù dto.Addressbiz.Address không giống như các loại, nhưng có cùng tên thuộc tính.

Suy nghĩ của tôi là nếu tên thuộc tính Gốc được viết giống nhau, ví dụ: AddressList, sau đó nó sẽ không quan trọng nếu 2 đối tượng cơ bản là các loại khác nhau. Nó vẫn sẽ sao chép các loại đơn giản cùng tên như int, chuỗi vv

cảm ơn bạn

+0

có bạn nhìn vào trang Cloning sâu từ trang CodePlex ValueInjecter không? http://valueinjecter.codeplex.com/wikipage?title=Deep%20Cloning&referringTitle=Home – Omu

+0

Xin chào Chuck. Vâng tôi đã làm. Nó không làm sâu sắc các thực thể con [nhibernate] của tôi – user52212

+0

nó sẽ rất hay nếu bạn đăng một số mã, và về các kiểu khác nhau, hàm injectFrom() tiêm từ cùng tên và cùng loại, vì vậy nó sẽ không ảnh hưởng đến các thành viên các loại khác nhau (và nếu bạn đang làm từ một loại khác không phải là nhân bản nữa, đó là lý do tại sao DeepClone không làm việc cho bạn) – Omu

Trả lời

7

Tôi đã gặp vấn đề tương tự khi các mảng/danh sách trong các đối tượng có cùng tên nhưng khác nhau (ví dụ một property được đặt tên là Animals of type ORMAnimals [] ánh xạ tới một thuộc tính có tên là Animals of type Animals []).

Với một số tinh chỉnh nhỏ để mã mẫu Chuck Norris có trên Deep Cloning page Tôi đã làm việc trong mã thử nghiệm của tôi:

public class CloneInjection : ConventionInjection 
{ 
    protected override bool Match(ConventionInfo c) 
    { 
     return c.SourceProp.Name == c.TargetProp.Name && c.SourceProp.Value != null; 
    } 

    protected override object SetValue(ConventionInfo c) 
    { 
     //for value types and string just return the value as is 
     if (c.SourceProp.Type.IsValueType || c.SourceProp.Type == typeof(string) 
      || c.TargetProp.Type.IsValueType || c.TargetProp.Type == typeof(string)) 
      return c.SourceProp.Value; 

     //handle arrays 
     if (c.SourceProp.Type.IsArray) 
     { 
      var arr = c.SourceProp.Value as Array; 
      var clone = Activator.CreateInstance(c.TargetProp.Type, arr.Length) as Array; 

      for (int index = 0; index < arr.Length; index++) 
      { 
       var a = arr.GetValue(index); 
       if (a.GetType().IsValueType || a.GetType() == typeof(string)) continue; 
       clone.SetValue(Activator.CreateInstance(c.TargetProp.Type.GetElementType()).InjectFrom<CloneInjection>(a), index); 
      } 
      return clone; 
     } 


     if (c.SourceProp.Type.IsGenericType) 
     { 
      //handle IEnumerable<> also ICollection<> IList<> List<> 
      if (c.SourceProp.Type.GetGenericTypeDefinition().GetInterfaces().Contains(typeof(IEnumerable))) 
      { 
       var t = c.TargetProp.Type.GetGenericArguments()[0]; 
       if (t.IsValueType || t == typeof(string)) return c.SourceProp.Value; 

       var tlist = typeof(List<>).MakeGenericType(t); 
       var list = Activator.CreateInstance(tlist); 

       var addMethod = tlist.GetMethod("Add"); 
       foreach (var o in c.SourceProp.Value as IEnumerable) 
       { 
        var e = Activator.CreateInstance(t).InjectFrom<CloneInjection>(o); 
        addMethod.Invoke(list, new[] { e }); // in 4.0 you can use dynamic and just do list.Add(e); 
       } 
       return list; 
      } 

      //unhandled generic type, you could also return null or throw 
      return c.SourceProp.Value; 
     } 

     //for simple object types create a new instace and apply the clone injection on it 
     return Activator.CreateInstance(c.TargetProp.Type) 
      .InjectFrom<CloneInjection>(c.SourceProp.Value); 
    } 
} 
+0

addMethod.Invoke (danh sách, mới [] {e}); // trong 4.0 bạn có thể sử dụng động và chỉ cần làm list.Add (e); Có ai đã làm điều này không? Tôi đã cố gắng bằng cách thay thế 'var danh sách' với 'danh sách năng động' và sau đó làm list.Add (e), mà biên dịch nhưng ném một ngoại lệ thời gian chạy. –

+0

@Gloopy - Đã cố gắng điều này nhưng tôi vẫn nhận được tràn ngăn xếp: ( – Ryan

+0

@Ryan là nó có thể một trong các đối tượng của bạn có một tham chiếu trở lại chính nó hoặc một đối tượng cha mẹ gây ra một vòng lặp vô hạn trong khi đi qua các con? – Gloopy