首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实体框架(6)性能优化建议

实体框架(6)性能优化建议
EN

Stack Overflow用户
提问于 2013-06-20 22:35:01
回答 2查看 6.2K关注 0票数 0

我的应用程序中有一个ADO.Net数据访问层,它使用基本的ADO.Net和CRUD存储过程(每个操作一个,例如Select_myTable、Insert_myTable)。正如您可以想象的那样,在一个大型系统(如我们的系统)中,DA层所需的DB对象的数量非常大。

我一直在研究将layer类重构为EF POCO类的可能性。我已经设法做到了这一点,但当我尝试性能测试时,它变得相当可怕。使用下面的类(create object,set Key to desired value,调用dataselect),100000次数据加载只需要大约47秒(数据库中只有几条记录)。而存储的Proc方法大约需要7秒。

我正在寻找关于如何优化这一点的建议-需要注意的是,我不能改变层公开的功能-只改变它如何实现方法(即我不能将上下文所有权的责任传递给BO层)。

谢谢

代码语言:javascript
复制
public class DAContext : DbContext
{
    public DAContext(DbConnection connection, DbTransaction trans)
        : base(connection, false)
    {
        this.Database.UseTransaction(trans);

    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        //Stop Pluralising the Object names for table names.
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        //Set any property ending in "Key" as a key type.
        modelBuilder.Properties().Where(prop => prop.Name.ToLower().EndsWith("key")).Configure(config => config.IsKey());

    }

    public DbSet<MyTable> MyTable{ get; set; }
}

public class MyTable : DataAccessBase
{

    #region Properties

    public int MyTableKey { get; set; }

    public string Name { get; set; }
    public string Description { get; set; }
    public bool Active { get; set; }
    public int CreatedBy { get; set; }
    public DateTime CreatedDate { get; set; }
    public int ModifiedBy { get; set; }
    public DateTime ModifiedDate { get; set; }

    #endregion

    #region constructors

    public MyTable()
    {
        //Set Default Values.
        Active = true;
        Name = string.Empty;
        CreatedDate = DateTime.MinValue;
        ModifiedDate = DateTime.MinValue;
    }

    #endregion

    #region Methods

    public override void DataSelect(System.Data.SqlClient.SqlConnection connection, System.Data.SqlClient.SqlTransaction transaction)
    {
        using (DAContext ctxt = new DAContext(connection, transaction))
        {

            var limitquery = from C in ctxt.MyTable
                             select C;


            //TODO: Sort the Query
            limitquery = FilterQuery(limitquery);

            var limit = limitquery.FirstOrDefault();

            if (limit != null)
            {
                this.Name = limit.Name;
                this.Description = limit.Description;
                this.Active = limit.Active;
                this.CreatedBy = limit.CreatedBy;
                this.CreatedDate = limit.CreatedDate;
                this.ModifiedBy = limit.ModifiedBy;
                this.ModifiedDate = limit.ModifiedDate;
            }
            else
            {
                throw new ObjectNotFoundException(string.Format("No MyTable with the specified Key ({0}) exists", this.MyTableKey));
            }
        }
    }

    private IQueryable<MyTable1> FilterQuery(IQueryable<MyTable1> limitQuery)
    {
        if (MyTableKey > 0) limitQuery = limitQuery.Where(C => C.MyTableKey == MyTableKey);
        if (!string.IsNullOrEmpty(Name)) limitQuery = limitQuery.Where(C => C.Name == Name);
        if (!string.IsNullOrEmpty(Description)) limitQuery = limitQuery.Where(C => C.Description == Description);
        if (Active) limitQuery = limitQuery.Where(C => C.Active == true);
        if (CreatedBy > 0) limitQuery = limitQuery.Where(C => C.CreatedBy == CreatedBy);
        if (ModifiedBy > 0) limitQuery = limitQuery.Where(C => C.ModifiedBy == ModifiedBy);
        if (CreatedDate > DateTime.MinValue) limitQuery = limitQuery.Where(C => C.CreatedDate == CreatedDate);
        if (ModifiedDate > DateTime.MinValue) limitQuery = limitQuery.Where(C => C.ModifiedDate == ModifiedDate);

        return limitQuery;
    }

    #endregion


}
EN

回答 2

Stack Overflow用户

发布于 2013-06-21 00:07:52

启用跟踪时,选择速度会很慢。您绝对应该关闭跟踪并再次测量。

看看我的基准测试

http://netpl.blogspot.com/2013/05/yet-another-orm-micro-benchmark-part-23_15.html

票数 1
EN

Stack Overflow用户

发布于 2013-10-30 19:57:14

这可能只是个预感但是..。在您的存储过程中,过滤器定义良好,SP处于编译状态,具有良好的执行计划。您的EF查询是从头开始构造的,并在每次使用时重新编译。因此,现在的任务是设计一种方法,在两次使用之间编译和保存您的EF查询。一种方法是重写FilterQuery,使其不依赖于流畅的条件方法链。不是每次参数集更改时都附加或不附加新条件,而是将其转换为一个条件,当满足条件时应用筛选器,或者在不满足条件时由1.Equals(1)之类的内容覆盖。这样就可以编译您的查询,并使其可供重用。支持SQL看起来很时髦,但执行时间应该会有所改善。或者,您可以设计面向方面的编程方法,根据参数值重用编译后的查询。如果我有时间,我会在Code Project上发布一个示例。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17216494

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档