2013-02-07 37 views
4

所以我們有如下兩種方法:重構重複Lambda表達式

方法1

private IEnumerable<object> CreateCentreViewModelForExport(IQueryable<CentreTranslation> centreTranslation) 
{ 
    return centreTranslation.Select(s => new 
    { 
     id = s.Centre.id, 
     centreTranslationId = s.id, 
     name = s.Centre.name, 
     number = s.Centre.number, 
     date_opened = s.Centre.date_opened, 
     address_line_1 = s.address_line_1, 
     address_line_2 = s.address_line_2, 
     address_line_3 = s.address_line_3, 
     city = s.city, 
     county = s.county, 
     country = s.Centre.Country.name, 
     //country_id = s.Centre.country_id, 
     translatedCountry = s.country, 
     postcode = s.postcode, 
     hidden = !(s.Centre.CentreStatus.Where(w => w.environment_id == 4).FirstOrDefault().active), 
     about = s.about, 
     virtualTour = s.Centre.virtual_tour, 
     directions = s.directions, 
     phone = s.Centre.phone, 
     fax = s.Centre.fax, 
     email = s.Centre.email, 
     lat = s.Centre.position.Latitude, 
     lng = s.Centre.position.Longitude, 
     imageCount = s.Centre.image_count, 
     translatedCentreName = s.name, 
     amenities = s.amenities , 
     features = s.FeatureTranslations.Select(s2 => new FeatureViewModel() 
     { 
      id = s2.id, 
      name = s2.Feature.name, 
      selected = s2.selected 
     }), 
     businessCentreAbout = s.ProductTranslations.Where(w => w.Product.id == (int)Products.BusinessCentre).FirstOrDefault().about, 
     officeSpaceAbout = s.ProductTranslations.Where(w => w.Product.id == (int)Products.OfficeSpace).FirstOrDefault().about, 
     virtualOfficeAbout = s.ProductTranslations.Where(w => w.Product.id == (int)Products.VirtualOffice).FirstOrDefault().about, 
     meetingRoomsAbout = s.ProductTranslations.Where(w => w.Product.id == (int)Products.MeetingRooms).FirstOrDefault().about, 
     businessLoungeAbout = s.ProductTranslations.Where(w => w.Product.id == (int)Products.BusinessLounge).FirstOrDefault().about, 
     dayOfficeAbout = s.ProductTranslations.Where(w => w.Product.id == (int)Products.DayOffice).FirstOrDefault().about, 
     language_group = s.Language.language_group, 
     culture = s.Language.cuture 
    }); 
} 

方法2

private IQueryable<CentreViewModel> CreateCentreViewModel(IQueryable<CentreTranslation> centreTranslation) 
{ 
    return centreTranslation.Select(s => new CentreViewModel() 
    { 
     id = s.Centre.id, 
     centreTranslationId = s.id, 
     name = s.Centre.name, 
     number = s.Centre.number, 
     date_opened = s.Centre.date_opened, 
     address_line_1 = s.address_line_1, 
     address_line_2 = s.address_line_2, 
     address_line_3 = s.address_line_3, 
     city = s.city, 
     county = s.county, 
     //country = s.Centre.Country.name, 
     country_id = s.Centre.country_id, 
     translatedCountry = s.country, 
     postcode = s.postcode, 
     hidden = !(s.Centre.CentreStatus.Where(w => w.environment_id == 4).FirstOrDefault().active), 
     about = s.about, 
     virtualTour = s.Centre.virtual_tour, 
     directions = s.directions, 
     phone = s.Centre.phone, 
     fax = s.Centre.fax, 
     email = s.Centre.email, 
     lat = s.Centre.position.Latitude, 
     lng = s.Centre.position.Longitude, 
     imageCount = s.Centre.image_count, 
     translatedCentreName = s.name, 
     amenities = s.amenities, 
     features = s.FeatureTranslations.Select(s2 => new FeatureViewModel() 
     { 
      id = s2.id, 
      name = s2.Feature.name, 
      selected = s2.selected 
     }), 
     businessCentreAbout = s.ProductTranslations.Where(w => w.Product.id == (int)Products.BusinessCentre).FirstOrDefault().about, 
     officeSpaceAbout = s.ProductTranslations.Where(w => w.Product.id == (int)Products.OfficeSpace).FirstOrDefault().about, 
     virtualOfficeAbout = s.ProductTranslations.Where(w => w.Product.id == (int)Products.VirtualOffice).FirstOrDefault().about, 
     meetingRoomsAbout = s.ProductTranslations.Where(w => w.Product.id == (int)Products.MeetingRooms).FirstOrDefault().about, 
     businessLoungeAbout = s.ProductTranslations.Where(w => w.Product.id == (int)Products.BusinessLounge).FirstOrDefault().about, 
     dayOfficeAbout = s.ProductTranslations.Where(w => w.Product.id == (int)Products.DayOffice).FirstOrDefault().about 
    }); 
} 

可以看出是有很多重複的代碼。第二種方法返回一個強類型的視圖模型,而第一個方法返回一個對象,因爲包含了兩個額外的屬性(language_group和culture)。

第二種方法用於填充MVC視圖,第二種方法用於導出到Excel函數。 重新分解這個以減少重複的最佳方式是什麼?

+1

總是使用'CentreViewModel',如果不需要'language'和'culture' null? – paul

+0

更適合[代碼評論](http://codereview.stackexchange.com/)。 –

+0

從一半的答案看來,我應該放棄 NiceYellowEgg

回答

1

創建於CentreViewModel類的靜態FromCentreTranslation方法,並把所有的初始化有:

public class CentreViewModel 
{ 
    .... 
    public static CentreViewModel FromCentreTranslation(CentreTranslation source) 
    { 
     CentreViewModel result = new CentreViewModel(); 
     result.id = source.Centre.id, 
     result.centreTranslationId = source.id, 
     result.name = source.Centre.name, 
     .... 
     result.businessLoungeAbout = source.ProductTranslations 
         .Where(w => w.Product.id == (int)Products.BusinessLounge) 
         .FirstOrDefault().about, 
     result.dayOfficeAbout = source.ProductTranslations 
         .Where(w => w.Product.id == (int)Products.DayOffice) 
         .FirstOrDefault().about 
     return result; 
    } 
} 

然後,您可以重構原始的兩個方法,如:

private IEnumerable<object> CreateCentreViewModelForExport 
           (IQueryable<CentreTranslation> centreTranslation) 
{ 
    return centreTranslation.Select(s => new 
    { 
     centreViewModel = CentreViewModel.FromCentreTranslation(s), 
     language_group = s.Language.language_group, 
     culture = s.Language.cuture 
    } 
} 

private IQueryable<CentreViewModel> CreateCentreViewModel 
           (IQueryable<CentreTranslation> centreTranslation) 
{ 
    return centreTranslation.Select(s => CentreViewModel.FromCentreTranslation(s)), 
} 
+0

看起來相當優雅,是適當的,把這種功能的ViewModel? – NiceYellowEgg

+0

這是你的電話。你也可以把它放在'CentreTranslation'類中,並把它稱爲'ToCentreViewModel',或者在另一個映射器類中。 – SWeko

3

我會創建一個DTO類,並有一個setter方法,它需要在IQueryable centreTranslation中。然後,您將該對象傳遞給該類,並在該類中設置所有這些值,並將該dto傳遞迴原來的方法。

public class SomeDto 
    { 
     //All of the properties your setting in the other method 

     public void SetDto(IQueryable<CentreTranslation> centreTranslation) 
     { 
      //call methods that set all the properties 
     } 

     private SetAddress(IQueryable<CentreTranslation> centreTranslation) 
     { 
      //set only address properties 
     } 

我也將做的類型,如具有做一個地址就在DTO對象調用SetAddress的私有方法和下井樣樣在行較小setter方法。

當你有你的DTO對象後,你可以使用像Automapper這樣的工具直接從你的DTO對象映射到ViewModel對象。這會給你最大的靈活性,以便在整個應用程序中進行更多的重構。

private ViewModel createViewModel(Dto) 

{ 
    return Mapper.Map(Dto, ViewModel);  
} 
+0

我喜歡Automapper,但我不能完全想象你是什麼在這裏說:) – NiceYellowEgg

+0

k我會澄清 – Robert

1
private IQueryable<object> CreateCentreViewModel(IQueryable<CentreTranslation> centreTranslation) 
{ 
    return centreTranslation.Select(s => new 
    { 
     model = new CentreViewModel() 
     { 
      id = s.Centre.id, 
      centreTranslationId = s.id, 
      name = s.Centre.name, 
      [...] 
     } 
     language_group = s.Language.language_group, 
     culture = s.Language.cuture 
    } 
}