2012-11-23 6 views
4

어떻게 든 genericise하고 메서드로 호출하려는 EntityFramework 백업 리포지토리에 다시 코드 블록이 있으므로 코드를 반복하지 말고 다시 사용하십시오.코드를 일반 메서드로 리팩터링

현재 코드 블록은 다음과 같다 :

 // Archive deleted MyItems sections 
     _t.MyItems.Where(x => x.ValidTo == null && !team.MyItems.Contains(x)).ToList().ForEach(x => x.ValidTo = DateTime.Now); 

     // Add or update MyItems sections 
     foreach (var MyItemsSection in team.MyItems) 
     { 
      if (MyItemsSection.Id == default(int)) 
      { 
       MyItemsSection.ValidFrom = DateTime.Now; 
       _t.MyItems.Add(MyItemsSection); 
      } 
      else 
      { 
       var _MyItemsSection = _t.MyItems.FirstOrDefault(x => x.Id == MyItemsSection.Id); 
       context.Entry(_MyItemsSection).CurrentValues.SetValues(MyItemsSection); 
      } 
     } 

_t가 EntityFramework 연결된 객체 그래프이다 team 뺐다 가능한 외부 업데이트 된 객체 그래프의 동일한 유형이있다. 목표는 두 개의 객체 그래프를 동기화하여 변경 사항이 지속되도록하는 것입니다.

는 같은 방법이 MyOtherItems 및 MySocks 작동, 그래서 내가 MyItems이 genericised 수 있습니다 _t.MyItems 및 team.MyItems에 전달해야

등 MyUnderPants

이 가능한 모든 있습니까?

+1

'MyItems'이'T'의 집합이라고 가정하면, 다른 모든'T'의 속성은'Id'와'ValidTo'입니까? 그게 더 일반화하고 다른 컬렉션과 함께 일하는 것을 고집하는 것 같습니다. – Jamiec

+0

codereview에 게시해야한다고 생각합니다. http://codereview.stackexchange.com/ – maxbeaudoin

+0

예, 모두 ID와 ValidTo가 있지만 컨텍스트가 있습니다. Entry(). CurrentValues.SetValues ​​()도 여전히 작동해야하므로이 두 속성을 기반으로하는 인터페이스는 작동하지 않습니다. 나는 그것을하는 법을 알지 못하지만, 타입을 전달할 필요가 있다는 것을 확신합니다. – Moo

답변

1

에서와 마찬가지로

, 여기에 대답 - 나는 실종됐다 당신이 특정 인터페이스를 구현으로 들어오는 유형을 필요로하며, 여전히로 사용할 수 있다는 사실이었다 원하는 유형.

그래서, 여기에 내가 생각 해낸 것입니다 :이 솔루션에 있던 where TEntity : class, IEntity

을 찾고 있었다

public void UpdateEntities<TEntity>(ICollection<TEntity> pocoCollection, ICollection<TEntity> dbCollection) 
     where TEntity : class, IEntity 
    { 
     // Archive deleted entities 
     dbCollection.Where(x => x.ValidTo == null && !pocoCollection.Contains(x)).ToList().ForEach(x => x.ValidTo = DateTime.Now); 

     // Add or update entities 
     foreach (var entity in pocoCollection) 
     { 
      if (entity.Id == default(int)) 
      { 
       entity.ValidFrom = DateTime.Now; 
       dbCollection.Add(entity); 
      } 
      else 
      { 
       var _entity = dbCollection.FirstOrDefault(x => x.Id == entity.Id); 
       context.Entry(_entity).CurrentValues.SetValues(entity); 
      } 
     } 
    } 

부분, 나는 나의 실체가 인터페이스를 구현 있는지 확인해야합니다 단순히 IEntity는 :

public interface IEntity 
{ 
    int Id { get; set;} 
    DateTime ValidFrom { get; set; } 
    DateTime? ValidTo { get; set; } 
} 

이 아직도 실제 유형을 사용할 수 있지만 컴파일러는 이러한 속성의 사용에 대해 불평을 종료 할 수 있습니다 따라서 Entity Framework도 만족스럽고 계속 진행되는 것에 대해 혼란스럽지 않습니다.

다른 사람에게 도움이되기를 바랍니다.

1

두 가지 선택 사항이 있습니다. 오브젝트를 일반 메소드에서 액세스하려는 특성 및 메소드가 들어있는 알려진 기본 유형으로 제한하거나 선택 술어를 사용하여 오브젝트를 제한하십시오.

제약 :

// base type 
interface IFoo { 
    int ID { get; set; } 
} 

    // generic method 
    public List<T> Update<T>(List<T> graph1, List<T> graph2) where T : IFoo { 
    var update = graph1.Intersect(graph2, (g1, g2) => { g1.ID == g2.ID }).ToList(); 
    return update; 
    } 

술어 :

public void Update<T, U>(T _t, T team, Func<T, IList<U>> selector) 
{ 
    var _tItems = selector(_t); 
    var teamItems = selector(team); 

    // Archive deleted MyItems sections 
    _tItems.Where(x => x.ValidTo == null && !teamItems.Contains(x)).ToList().ForEach(x => x.ValidTo = DateTime.Now); 

    // Add or update MyItems sections 
    foreach (var MyItemsSection in teamItems) 
    { 
     if (MyItemsSection.Id == default(int)) 
     { 
      MyItemsSection.ValidFrom = DateTime.Now; 
      _tItems.Add(MyItemsSection); 
     } 
     else 
     { 
      var _MyItemsSection = _tItems.FirstOrDefault(x => x.Id == MyItemsSection.Id); 
      context.Entry(_MyItemsSection).CurrentValues.SetValues(MyItemsSection); 
     } 
    } 
} 

    //Usage: 
    Update(_t, team, (t => t.MyItems)); 

하지만 다시, 매개 변수로 목록을 소요하는 방법을 쓰기에서 당신을 유지 무엇? 내 자신의 질문에 대한 대답에서 public void Update<T>(IList<T> _tItems, IList<T> teamItems)

+0

기본 유형을 제약하는 것은 작동하지 않을 것입니다. 왜냐하면 그것들이 다르기 때문입니다. 제가 제네릭 화하려는 구조는 EF가 내 방식보다 어떻게 작동하는지에 대한 결과물이므로 EF는 여전히 그 일을 할 수 있어야합니다. 내가 알아 챘는지 모르겠지만 내 코드 예제에는 삭제 된 항목 보관, 새 항목 추가 및 기존 항목 업데이트 등 세 가지 작업이 있습니다. EF는 여러 가지 이유로 문제가되는 객체 그래프를 병합합니다. – Moo

+1

@Moo - T4 템플릿을 수정하거나 'partial' 클래스 객체의 다른 부분으로 새 파일에서 객체에 추가 할 수있는 기본 인터페이스로 제약 할 수 있습니다. 그것은 EF를 전혀 방해하지 않을 것이고, EF가 인터페이스가 요구하는 속성을 이미 생성하고 있다면, 당신은 다른 것을 할 필요가 없습니다. – Bobson

+0

나는 그것을 이해하지만 context.Entry(). CurrentValues.SetValues ​​()는 예상 유형 (즉, 엔티티)이 아닌 다른 유형을 가져오고있는 것으로 알고 있습니까? 엔티티를 Entry()와 SetValues ​​()에 모두 전달할 수 있기 때문에 제한된 유형을 전달하면 EF가 그 두 가지 엔티티 유형을 전달한다는 사실을 완전히 놓치지 않을 것이라고 완전히 확신하지는 않습니다. 그것은 대략 알고있다. 말이 돼? – Moo

관련 문제