我正在尝试在大型物业管理系统的存储库层中重构一些非常慢的代码。
原始开发团队遵循了一种模式,他们不了解有关IQueryable的延迟执行的性质。
以下是代码示例:
public PropertyDTO GetPropertyByPropertyAuctionID(Guid propertyAuctionId)
{
PropertyDTO property = null;
var result =
(
from pa in databaseContext.PropertyAuction
join a in databaseContext.Auction on pa.AuctionID equals a.AuctionID into suba
from sa in suba.DefaultIfEmpty()
join an in databaseContext.AuctionNotifications
on sa.AuctionNotificationsID equals an.AuctionNotificationsID into suban
from san in suban.DefaultIfEmpty()
where pa.PropertyAuctionID == propertyAuctionId
where pa.IsDeleted == null || !(bool)pa.IsDeleted
select new
{
PropertyAuction = pa,
AuctionNotifications = san
}
).FirstOrDefault();
if (result != null)
{
var start = DateTime.Now;
property = ConvertPropertyFromDatabase(result.PropertyAuction, result.AuctionNotifications);
//end can be upwards of 10-12 seconds per record
var end = DateTime.Now - start;
}
else
{
throw CustomException.NotFound;
}
return property;
}
internal PropertyDTO ConvertPropertyFromDatabase(PropertyAuction propertyAuction, AuctionNotifications auctionNotifications = null)
{
Property property = null;
PropertyDTO dtoProperty = new PropertyDTO()
{
PropertyAuctionID = propertyAuction.PropertyAuctionID
};
if (propertyAuction.PropertyID.HasValue)
{
dtoProperty.PropertyID = propertyAuction.PropertyID.Value;
property = propertyAuction.Property;
dtoProperty.IsSimulcastAuction = propertyAuction.IsSimulcastAuction;
dtoProperty.IsSold = propertyAuction.IsSold;
dtoProperty.PropertyExecutionInitialValue = propertyAuction.ExecutionInitialValue;
}
if (propertyAuction.User4 != null && !string.IsNullOrEmpty(propertyAuction.User4.Profile1.FirstName) && !string.IsNullOrEmpty(propertyAuction.User4.Profile1.LastName))
{
dtoProperty.OfferAdministratorFirstName = propertyAuction.User4.Profile1.FirstName;
dtoProperty.OfferAdministratorLastName = propertyAuction.User4.Profile1.LastName;
dtoProperty.OfferAdministratorUserID = propertyAuction.OfferAdministratorUserID;
}
if (propertyAuction.AuctionID.HasValue)
{
dtoProperty.AuctionID = propertyAuction.AuctionID;
string auctionStartDateString = String.Empty;
if (propertyAuction.Auction != null)
{
if (propertyAuction.Auction.AuctionStartDate.HasValue)
{
auctionStartDateString = propertyAuction.Auction.AuctionStartDate.Value.Year + "-" + propertyAuction.Auction.AuctionStartDate.Value.Month.ToString().PadLeft(2, '0') + "-" + propertyAuction.Auction.AuctionStartDate.Value.Day.ToString().PadLeft(2, '0') + ": ";
}
dtoProperty.HMOnlineAuctionClosingStartDate = propertyAuction.Auction.AuctionClosingDate;
dtoProperty.AuctionName = auctionStartDateString + propertyAuction.Auction.Title;
dtoProperty.AuctionPublicSiteName = propertyAuction.Auction.PublicSiteName;
dtoProperty.AuctionNumber = propertyAuction.Auction.AuctionNumber;
dtoProperty.AuctionType = propertyAuction.Auction.AuctionType.Value;
dtoProperty.OriginalAuctionID = propertyAuction.Auction.OriginalAuctionID;
dtoProperty.AuctionTermsAndConditions = propertyAuction.Auction.TermsAndConditions;
dtoProperty.BrochureFileName = propertyAuction.Auction.BrochureFileName;
dtoProperty.BrochureName = propertyAuction.Auction.BrochureName;
if (propertyAuction.Auction.LuJohnsAuctionDetails != null)
{
dtoProperty.LuJohnsAuctionLiveWebcastLink = propertyAuction.Auction.LuJohnsAuctionDetails.LiveWebcastLink;
}
}
}
if (propertyAuction.PropertyStatus != null)
{
dtoProperty.PropertyStatusID = propertyAuction.PropertyStatusID.Value;
dtoProperty.PropertyStatusValue = propertyAuction.PropertyStatus.Value;
}
if (propertyAuction.PropertyAuctionAuctionDetails != null)
{
PropertyAuctionAuctionDetails propertyAuctionAuctionDetails = propertyAuction.PropertyAuctionAuctionDetails;
dtoProperty.PropertyAuctionAuctionDetailsId = propertyAuction.PropertyAuctionAuctionDetailsID;
SetShowOnWebsiteProperty(dtoProperty, propertyAuction);
SetWebsiteButtonProperty(dtoProperty, propertyAuctionAuctionDetails, propertyAuctionAuctionDetails.PreSaleMethod,
propertyAuctionAuctionDetails.AuctionMethod, propertyAuctionAuctionDetails.PostSaleMethod);
}
//This goes on for an astounding 900 more lines of code
}
正如您可能猜到的那样,这会重复访问数据库。
重构此代码以最少访问数据库的最快方法是什么?
答案 0 :(得分:0)
这里的问题是这个ConvertPropertyFromDatabase()
方法会触发大量的延迟加载属性查询。我建议您在DbContext
类中转为延迟加载,如下所示:
Configuration.LazyLoadingEnabled = false;
然后你必须检查在这个转换方法中访问了哪些属性,并重写你的查询,以便显式加载它们。