2012-02-02 3 views
0

두 개의 메모리 내 컬렉션을 LINQ- 개체로 병합하는 가장 효율적인 방법을 찾는 데 도움이 필요합니다. 내 경우에는 속성 값에 따라 특정 항목을 제외해야하기 때문에 단순한 조인이나 연결이 아닙니다. 두 컬렉션을 LINQ- 개체로 조건부로 병합

은의 다음과 같은 예를 사용하자 (매우 현실적이지,하지만 내가 필요한 것을 설명) :

public abstract class Person 
{ 
    public String Name { get; set; } 
} 

public class Employee : Person 
{ 
    public DateTime? TerminationDate { get; set; } 
} 

public class Customer : Person 
{ 
    ... 
} 

주, 직원도 고객이 될 수 있습니다.

나는 종업원의 목록과 고객의 목록을 가지고 있고 이러한 규칙에 따라 모든 사람의 목록을 생성 할 :도없는 그

  • 모든 직원 또한 종업원 수없는

    1. 모든 고객 고객 및 종료되지 않습니다 (TerminationDate == NULL)
    2. 고객과 직원 모두 AND (TerminationDate == null이)를 종료하지 않는 모든 사람

    ㅁ 이 일을 수행하는 가장 효율적인 방법은 무엇입니까?

  • +1

    고객은, 어쨌든 직원이 될 수 없습니다. "직원 **과 같은 이름의 ** 고객을 제외 하시겠습니까?" –

    +0

    사람들은 분명히 직원과 고객이 동시에 상속 할 수 있기 때문에 상속은 개체를 모델링하는 가장 적절한 방법이 아닐 수 있습니다. 나는이 경우 상속에 대한 구성을 선호 할 것이다. –

    +0

    예, 제가 직원이 고객 일 수도 있다고 말했을 때, 저는 실제 세계가 아니라 물건을 의미했습니다. 혼란을 드려 죄송합니다. – SonOfPirate

    답변

    0

    반드시 잘못된 것은 아니지만는 제임스의 예를 내가 바라고 내가 최종 결과로 하나의 목록을 필요로하는 불완전 것을 좀 더 복잡하다.

    확실하지 않음이 중, 가장 좋은 방법이지만, 여기 내가 지금까지 해낸 무엇 : 서로 다른 클래스이기 때문에

    public abstract class Person 
    { 
        public String Name { get; set; } 
    
        public override Boolean Equals(Object other) 
        { 
         var otherPerson = other as Person; 
    
         if (otherPerson == null) 
          return false; 
    
         return Name.Equals(otherPerson.Name, StringComparison.OrdinalIgnoreCase); 
        } 
    } 
    
    public class Employee : Person 
    { 
        public DateTime? TerminationDate { get; set; } 
    } 
    
    public class Customer : Person 
    { 
        ... 
    } 
    
    
    public class People 
    { 
        private IEnumerable<Customer> Customers; 
        private IEnumerable<Employee> Employees; 
    
        public IEnumerable<Person> GetCurrentPeople() 
        { 
         // Find all customers that are not employees 
         var onlyCustomers = Customers.Except(Employees); 
    
         // We only want employees that have not been terminated 
         var currentEmployees = Employees.Where(e => e.TerminationDate == null); 
    
         // Find all customers that are also employees 
         var customerAndEmployees = currentEmployees.Intersect(Customers); 
    
         // Now deal with employees that are not customers 
         var onlyEmployees = currentEmployees.Except(Customers); 
    
         // Join the lists together 
         var mergedRules = onlyCustomers.Concat(onlyEmployees).Concat(customerAndEmployees); 
    
         return mergedRules; 
        } 
    } 
    
    0

    확실히 말하기는 어렵지만 Jon의 이름 일치가 맞다고 가정하면 개념적으로 의미가 있습니까?

    현재 다중 반복을 수행하므로 일반적으로 ToArray 등을 일부 위치에 추가하지만 개념적 비트의 유효성을 검사하는 동안이 코드에 추가하고 싶지 않습니다.

    var allPeople = ...; 
    
    var customers = allPeople.OfType<Customer>(); 
    var employees = allPeople.OfType<Employee>(); 
    
    var employeeNames = new HashSet(employees.Select(p => p.Name)); 
    var customerNames = new HashSet(employees.Select(p => p.Name)); 
    
    // list item #1 
    var customersNotEmployees = customers 
        .Where(c => employeeNames.Contains(c.Name) == false); 
    
    // will be used by #2 and #3 
    var employeesNotTerminated = employees 
        .Where(e => e.TerminationDate == null); 
    
    // list item #2 
    var employeesNotCustomersAndNotTerminated = employeesNotTerminated 
        .Where(e => customerNames.Contains(e.Name) == false); 
    
    // list item #3 
    var employeesAndCustomersAndNotTerminated = employeesNotTerminated 
        .Where(e => customerNames.Contains(e.Name) == true); 
    
    관련 문제