合并这两种非常相似的方法

Jos*_*jos 1 c# asp.net

我在服务上有这两种方法:

public Offer GetOffer(int id, string languageCode = Website.LanguageSettings.DefaultLanguageCode)
        {
            Entities.Offer offerEntity = _db.Offers.FirstOrDefault(offer => offer.Id == id);

            if (languageCode.ToLower(CultureInfo.InvariantCulture) != Website.LanguageSettings.DefaultLanguageCode)
            {
                using (IDocumentSession session = store.OpenSession())
                {
                    Translation.Offer translatedOffer = session.LuceneQuery<Translation.Offer>(Website.RavenDbSettings.Indexes.Offers)
                        .Where(string.Format("ObjectId:{0} AND LanguageCode:{1}", id, languageCode))
                        .OrderByDescending(offer => offer.Id)
                        .FirstOrDefault();

                    var offerPOCO = Mapper.DynamicMap<Translation.Offer, Offer>(translatedOffer);
                    offerPOCO.Id = offerEntity.Id;

                    return offerPOCO;
                }
            }

            return Mapper.Map<Entities.Offer, Offer>(offerEntity);
        }
Run Code Online (Sandbox Code Playgroud)

public Hotel GetHotel(int id, string languageCode = Website.LanguageSettings.DefaultLanguageCode)
        {
            Entities.Hotel hotelEntity = _db.Hotels.FirstOrDefault(hotel => hotel.Id == id);

            if (languageCode.ToLower(CultureInfo.InvariantCulture) != Website.LanguageSettings.DefaultLanguageCode)
            {
                using(IDocumentSession session = store.OpenSession())
                {
                    Translation.Hotel translatedHotel = session.LuceneQuery<Translation.Hotel>(Website.RavenDbSettings.Indexes.Hotels)
                        .Where(string.Format("ObjectId:{0} AND LanguageCode:{1}", id, languageCode))
                        .OrderByDescending(hotel => hotel.Id)
                        .FirstOrDefault();

                    Hotel hotelPOCO = Mapper.DynamicMap<Translation.Hotel, Hotel>(translatedHotel);
                    hotelPOCO.Id = hotelEntity.Id;

                    return hotelPOCO;
                }
            }

            return Mapper.Map<Entities.Hotel, Hotel>(hotelEntity);
        }
Run Code Online (Sandbox Code Playgroud)

它们在大多数方面完全相同:它们采用相同的参数,构建相同的查询并进行相同的操作,唯一不同的是它们使用和输出的对象类型.除了构建一个生成Where()参数字符串的方法之外,我想不出任何方法可以将大部分(或全部)此代码合并到一个方法中,然后从GetOffer()和GetHotel()中调用它方法,因为我最终会得到更多这样的两个.

任何意见是极大的赞赏.

编辑:添加解决方案,如果另一个可怜的灵魂遇到这个问题,他/她可以有一个起点:

private TReturn GetObject<TReturn, TEntity, TTranslation>(int id, string languageCode, string ravenDbIndex) where TEntity:EntityObject 
                                                                                                                    where TTranslation:Translation.BaseTranslationObject
                                                                                                                    where TReturn:BasePOCO
        {
            // TODO Run more tests through the profiler
            var entities = _db.CreateObjectSet<TEntity>();
            var entityKey = new EntityKey(_db.DefaultContainerName + "." + entities.EntitySet.Name, "Id", id); // Sticking to the Id convention for the primary key
            TEntity entity = (TEntity)_db.GetObjectByKey(entityKey);

            if(languageCode.ToLower(CultureInfo.InvariantCulture) != Website.LanguageSettings.DefaultLanguageCode)
            {
                using(IDocumentSession session = store.OpenSession())
                {
                    TTranslation translatedObject = session.LuceneQuery<TTranslation>(ravenDbIndex)
                        .Where(string.Format("ObjectId:{0} AND LanguageCode:{1}", id, languageCode))
                        .OrderByDescending(translation => translation.Id)
                        .FirstOrDefault();

                    TReturn poco = Mapper.DynamicMap<TTranslation, TReturn>(translatedObject);
                    poco.Id = id;

                    return poco;
                }
            }

            return Mapper.Map<TEntity, TReturn>(entity);
        }
Run Code Online (Sandbox Code Playgroud)

然后我打电话给:

GetObject<Hotel, Entities.Hotel, Translation.Hotel>(id, languageCode, Website.RavenDbSettings.Indexes.Hotels);
Run Code Online (Sandbox Code Playgroud)

每当我需要一家酒店.

谢谢大家的回复,他们从中学到了很多.

Rus*_*Cam 6

看起来你可以将它重构成一个通用方法.类似于此的东西(我对重构某些方法调用的能力做了一些假设,等等.但希望你能得到这个想法)

public T Get<T>(int id, string languageCode = Website.LanguageSettings.DefaultLanguageCode)
        {
            Entity<T> entity = _db<T>.FirstOrDefault(entity => entity.Id == id);

            if (languageCode.ToLower(CultureInfo.InvariantCulture) != Website.LanguageSettings.DefaultLanguageCode)
            {
                using(IDocumentSession session = store.OpenSession())
                {
                    Translation<T> translatedEntity = session.LuceneQuery<Translation<T>>(Website.RavenDbSettings.Indexes.Entities<T>)
                        .Where(string.Format("ObjectId:{0} AND LanguageCode:{1}", id, languageCode))
                        .OrderByDescending(entity=> entity.Id)
                        .FirstOrDefault();

                    T POCO = Mapper.DynamicMap<Translation<T>, T>(translatedEntity);
                    POCO.Id = entity.Id;

                    return POCO;
                }
            }

            return Mapper.Map<Entities<T>, T>(Entity);
        }
Run Code Online (Sandbox Code Playgroud)