2013-08-01 2 views
0

LINQ를 통해 두 개의 목록이 반환됩니다. 내 목표는 '기본값'목록에서 'notDefaults'목록에있는 항목을 제외한 모든 항목을 반환하는 것입니다.linq을 사용하여 항목 제외

현재 두 개의 중첩 된 for 루프와 'RemoveAt'를 통해이 작업을 수행하고 있습니다. 이 작업은 단 하나의 LINQ 문으로 수행 할 수 있습니까? 기본적으로 'AssetPayrollMarkupOverrides'테이블에 항목이 없으면 '기본값'목록에 모든 항목이 필요합니다.

나는 it appears to be slow부터 'RemoveAt'를 사용하는 것에 대해 우려하고 있습니다.

var defaults = (from a in dbcontext.Assets 
    join b in dbcontext.AssetAddresses on a.AssetID equals b.AssetID 
    join c in dbcontext.Addresses on b.AddressID equals c.AddressID 
    join d in dbcontext.StateLookups on c.StateID equals d.StateID 
    where d.ShortName == state 
    select new AssetMarkup() 
    { 
     AssetId = a.AssetID, 
     AssetName = a.AssetName, 
     Seg1_Code = a.Seg1_Code, 
     ShortName = d.ShortName, 
     OfficePercentage = dbcontext.PayrollMarkups.Where(x => x.StateID == c.StateID).Select(x => x.OfficePercentage).FirstOrDefault(), 
     MaintenancePercentage = dbcontext.PayrollMarkups.Where(x => x.StateID == c.StateID).Select(x => x.MaintenancePercentage).FirstOrDefault(), 
     Note = dbcontext.AssetPayrollMarkupOverrides.Where(x => x.AssetID == a.AssetID).Select(x => x.Note).FirstOrDefault() 
    }).ToList(); 

var notDefaults = (from a in dbcontext.Assets 
    join b in dbcontext.AssetAddresses on a.AssetID equals b.AssetID 
    join c in dbcontext.Addresses on b.AddressID equals c.AddressID 
    join d in dbcontext.StateLookups on c.StateID equals d.StateID 
    join e in dbcontext.AssetPayrollMarkupOverrides on a.AssetID equals e.AssetID 
    where d.ShortName == state 
    select new AssetMarkup() 
    { 
     AssetId = a.AssetID, 
     AssetName = a.AssetName, 
     Seg1_Code = a.Seg1_Code, 
     ShortName = d.ShortName, 
     OfficePercentage = dbcontext.PayrollMarkups.Where(x => x.StateID == c.StateID).Select(x => x.OfficePercentage).FirstOrDefault(), 
     MaintenancePercentage = dbcontext.PayrollMarkups.Where(x => x.StateID == c.StateID).Select(x => x.MaintenancePercentage).FirstOrDefault(), 
     Note = dbcontext.AssetPayrollMarkupOverrides.Where(x => x.AssetID == a.AssetID).Select(x => x.Note).FirstOrDefault() 
    }).ToList(); 

return Json(defaults.Except(notDefaults).OrderBy(x => x.AssetName).ToDataSourceResult(request)); 

답변

0
var notDefaultIds = notDefaults.Select(nd => nd.AssetID); 
var result = defaults.Where(def => !notDefaultIds.Any(id => id == def.AssetID); 

참조;

4

당신은 Except

var remaining = defaults.Except(notDefaults); 

당신은 AssetMarkup가에 같음 비교를 보장해야 할 수 있습니다를 사용할 수 있습니다

var defaults = (from a in dbcontext.Assets 
    join b in dbcontext.AssetAddresses on a.AssetID equals b.AssetID 
    join c in dbcontext.Addresses on b.AddressID equals c.AddressID 
    join d in dbcontext.StateLookups on c.StateID equals d.StateID 
    where d.ShortName == state 
    select new AssetMarkup() 
    { 
     AssetId = a.AssetID, 
     AssetName = a.AssetName, 
     Seg1_Code = a.Seg1_Code, 
    }).ToList(); 


var notDefaults = (from a in dbcontext.Assets 
    join b in dbcontext.AssetAddresses on a.AssetID equals b.AssetID 
    join c in dbcontext.Addresses on b.AddressID equals c.AddressID 
    join d in dbcontext.StateLookups on c.StateID equals d.StateID 
    join e in dbcontext.AssetPayrollMarkupOverrides on a.AssetID equals e.AssetID 
    where d.ShortName == state 
    select new AssetMarkup() 
    { 
     AssetId = a.AssetID, 
     AssetName = a.AssetName, 
     Seg1_Code = a.Seg1_Code, 
     ShortName = d.ShortName, 
     OfficePercentage = e.OfficePercentage, 
     MaintenancePercentage = e.MaintenancePercentage, 
     Note = e.Note 
    }).ToList(); 

나는 원래 그것을 두 목록이 일치 있는지 확인하기 위해이 방법을했다 참조가 아닌 방식으로 객체를 비교하도록 설정합니다. 당신이 defaultsresult에, DB를 왕복을 줄일 수 notDefaults에서 ToList()를 이동하려면

여기 http://msdn.microsoft.com/en-us/library/ms173147(v=vs.80).aspx

+0

원래 게시글에이 사실을 밝히지 않았지만 '예외'를 ​​사용하려고했지만 그 기능이 작동하지 않는 것으로 사과합니다. 필자는 동일한 OfficePercentage, MaintenancePercentage 및 Notes를 각 linq 문에 추가하여 정확히 일치하는지 확인하고 'Except'가 여전히 작동하지 않는 것처럼 보였습니다. return Json (defaults.Except (notDefaults) .OrderBy (x => x.AssetName) .ToDataSourceResult (request)); – Mithrilhall

+0

AssetMarkup 개체를 적절하게 비교하는 방법으로 Equals 오버로드가 발생해야합니다. –

1

당신이 찾고있는 것은 두 세트 중 complement입니다. Linq의 Except() 방법은 (당신이 IEqualityComparer 걸리는 과부하를 사용할 수 있습니다)이 작업을 수행하도록 설계되었습니다

public class AssetMarkupComparer : IEqualityComparer<AssetMarkup> 
{ 
    public bool Equals(AssetMarkup am1, AssetMarkup am2) 
    { 
     return am1.AssetId == am2.AssetId; 
    } 

    public int GetHashCode(AssetMarkup obj) 
    { 
     return obj.AssetId.GetHashCode(); 
    } 
} 

var complement = defaults.Except(notDefaults, new AssetMarkupComparer()); 

당신은 비교 자 방법에 널 (null)을 설명해야 할 것이다 그러나 이것은 단지 해골 예입니다.

관련 문제