fin*_*yzh 13 .net c# asp.net entity-framework
我必须在数据库中记录Web服务调用.开始时,我首先使用代码EF来定义Entity类并生成数据库脚本.数据库部分非常简单,只有一个表.有一个主键:Id,其他列是string,datetime和float.共16列.
然后我运行了VS2012的性能分析.报告显示RecordUsageEF占用整个呼叫的一半时间,这太荒谬了.我尝试了MergeOption.NoTracking选项和预生成视图(如何:预生成视图以提高查询性能).但他们并没有多大帮助.
然后我尝试了Ado.net.我把sql脚本放在源代码中只是为了测试.一起调用2个方法来比较性能.
public static void RecordUsage(HttpContext httpContext, XmlWDCRecipe processedRecipe, string orgRecipe, string userName, ActionEnum action, bool trueview, string pageId)
{
RecordUsageEF(httpContext, processedRecipe, orgRecipe, userName, action, trueview, pageId);
RecordUsageADO(httpContext, processedRecipe, orgRecipe, userName, action, trueview, pageId);
}
Run Code Online (Sandbox Code Playgroud)
结果让我感到惊讶:
使用静态EF上下文更新了一些改进:

Inside RecordUsageEF:

更新了 Inside RecordUsageEF - 静态上下文

更新刚刚意识到默认性能是CPU采样,这是选择检测时的结果

它不是那么糟糕,但如果CPU是网站/网络服务的瓶颈.EF看起来不是一个好选择.
我检查了sql profiler中EF生成的脚本.它是一个非常简单的插入sql语句,它比Ado.net运行得更快.
我错过了EF吗?如果它处于这种性能水平,我不能使用EF.
这是源代码.
EF版本:
public static readonly LogContainer container = new LogContainer();
private static void RecordUsageEF(HttpContext httpContext, XmlWDCRecipe processedRecipe, string orgRecipe, string userName, ActionEnum action, bool trueview, string pageId)
{
{
container.Usages.MergeOption = System.Data.Objects.MergeOption.NoTracking;
using (LookupService ls = new LookupService(httpContext.Server.MapPath(geoDBLocation), LookupService.GEOIP_MEMORY_CACHE))
{
//get country of the ip address
Location location = s.getLocation(httpContext.Request.UserHostAddress);
Usage usage = new Usage()
{
Brand = brand,
Action = action.ToString(),
ExecuteDate = DateTime.Now,
OutputFormat = trueview ? Path.GetExtension(processedRecipe.Output.trueview_file) : Path.GetExtension(processedRecipe.Output.design_file),
Recipe = orgRecipe,
SessionId = pageId,
Username = userName,
ClientIP = httpContext.Request.UserHostAddress,
ClientCountry = location == null ? null : location.countryName,
ClientState = location == null ? null : location.regionName,
ClientCity = location == null ? null : location.city,
ClientPostcode = location == null ? null : location.postalCode,
ClientLatitude = location == null ? null : (double?)location.latitude,
ClientLongitude = location == null ? null : (double?)location.longitude,
UserAgent = httpContext.Request.UserAgent
};
//container.AddToUsages(usage);
container.Usages.AddObject(usage);
container.SaveChanges(System.Data.Objects.SaveOptions.None);
}
}
}
Run Code Online (Sandbox Code Playgroud)
EF设置是默认设置:

Ado.net版本:
private static void RecordUsageADO(HttpContext httpContext, XmlWDCRecipe processedRecipe, string orgRecipe, string userName, ActionEnum action, bool trueview, string pageId)
{
using (SqlConnection conn = new SqlConnection("data source=pgo_swsvr;initial catalog=OESDWebSizer;user id=sa;password=sa;MultipleActiveResultSets=True;"))
{
using (LookupService ls = new LookupService(httpContext.Server.MapPath(geoDBLocation), LookupService.GEOIP_MEMORY_CACHE))
{
//get country of the ip address
//test using "203.110.131.5" "58.63.236.236"
//httpContext.Request.UserHostAddress
Location location = ls.getLocation(httpContext.Request.UserHostAddress);
SqlCommand command = new SqlCommand();
conn.Open();
command.Connection = conn;
command.CommandType = System.Data.CommandType.Text;
command.CommandText = @"insert into Usages ([Brand],[Username],[SessionId],[Action],[Recipe],[ExecuteDate]
,[OutputFormat],[ClientIP],[ClientCountry],[ClientState],[ClientCity],[ClientPostcode]
,[ClientLatitude],[ClientLongitude],[UserAgent])
Values ('" + brand + "',"
+ (string.IsNullOrEmpty(userName) ? "NULL" : "'" + userName + "'") + ", '" + pageId + "', '" + action.ToString() + "', '" + orgRecipe + "', '" + DateTime.Now.ToString("yyyyMMdd") + "', '"
+ (trueview ? Path.GetExtension(processedRecipe.Output.trueview_file) : Path.GetExtension(processedRecipe.Output.design_file)) + "', '"
+ httpContext.Request.UserHostAddress + "', '"
+ (location == null ? string.Empty : location.countryName) + "', '"
+ (location == null ? string.Empty : location.regionName) + "', '"
+ (location == null ? string.Empty : location.city) + "', '"
+ (location == null ? string.Empty : location.postalCode) + "', "
+ (location == null ? 0 : (double?)location.latitude) + ", "
+ (location == null ? 0 : (double?)location.longitude) + ", '"
+ httpContext.Request.UserAgent + "')";
command.ExecuteNonQuery();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我最熟悉代码优先的处理方式,但如果您的容器对象是 DbContext,则以下内容应该会显着提高插入性能:
container.Configuration.AutoDetectChangesEnabled = false;
container.Configuration.ValidateOnSaveEnabled = false;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
404 次 |
| 最近记录: |