Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Linq到Sql惊人地快速地重新修改数据。它比ADO快10倍,这正常吗?_C#_Database_Linq_Nhibernate_Linq To Sql - Fatal编程技术网

C# Linq到Sql惊人地快速地重新修改数据。它比ADO快10倍,这正常吗?

C# Linq到Sql惊人地快速地重新修改数据。它比ADO快10倍,这正常吗?,c#,database,linq,nhibernate,linq-to-sql,C#,Database,Linq,Nhibernate,Linq To Sql,我目前正在学习LINQtoSQL,我对选择数据的性能感到非常惊讶。我正在从几个表中重新修改连接的数据。我选择了大约40k行。使用ADO将这些数据映射到对象的时间大约为35秒,使用NHbiernate将这些数据映射到对象的时间大约为130秒,而使用Linq到Sql的时间仅为3,5秒。此外,我还想指出,我使用的是立即加载,如下所示: THESIS th = new THESIS(connectionString); DataLoadOptions dlo = new DataLoadOptions(

我目前正在学习LINQtoSQL,我对选择数据的性能感到非常惊讶。我正在从几个表中重新修改连接的数据。我选择了大约40k行。使用ADO将这些数据映射到对象的时间大约为35秒,使用NHbiernate将这些数据映射到对象的时间大约为130秒,而使用Linq到Sql的时间仅为3,5秒。此外,我还想指出,我使用的是立即加载,如下所示:

THESIS th = new THESIS(connectionString);
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<NumericFormula>(x => x.RPN);
dlo.LoadWith<RPN>(x => x.RPNDetails);
dlo.LoadWith<RPNDetail>(x => x.Parameter);
th.LoadOptions = dlo;
th.Log = Console.Out;
论文th=新论文(连接字符串);
DataLoadOptions dlo=新的DataLoadOptions();
dlo.LoadWith(x=>x.RPN);
dlo.LoadWith(x=>x.RPNDetails);
dlo.LoadWith(x=>x.Parameter);
th.LoadOptions=dlo;
th.Log=Console.Out;
在迭代时查看日志,我看不到LINQtoSQL会向数据库生成一些额外的查询

我对表现上的巨大差异感到非常惊讶,我想也许我不明白什么

有人能解释一下为什么它工作得这么快吗? 我用秒表来测量时间

ADO.NET代码:

public static List<NumericFormulaDO> SelectAllNumericFormulas()
{
    var nFormulas = new List<NumericFormulaDO>();

    string queryString = @"
        SELECT *
        FROM    NumericFormula nf 
                Left Join Unit u on u.Unit_Id = nf.Unit_Id 
                Left Join UnitType ut on ut.UnitType_Id = u.UnitType_Id 
                Join RPN r on r.RPN_Id = nf.RPN_Id 
                Join RPNDetails rd on rd.RPN_Id = r.RPN_Id 
                Join Parameter par on par.Parameter_Id = rd.Parameter_Id where nf.NumericFormula_Id<=10000";

    using (var connection = new SqlConnection(connectionString))
    {
        var command = new SqlCommand(queryString, connection);
        connection.Open();
        using (var reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
                var det = new RPNDetailsDO();
                det.RPNDetails_Id = Int32.Parse(reader["RPNDetails_Id"].ToString());
                det.RPN_Id = Int32.Parse(reader["RPN_Id"].ToString());
                det.Identifier = reader["Identifier"].ToString();
                det.Parameter.Architecture = reader["Architecture"].ToString();
                det.Parameter.Code = reader["Code"].ToString();
                det.Parameter.Description = reader["Description"].ToString();
                det.Parameter.Parameter_Id = Int32.Parse(reader["Parameter_Id"].ToString());
                det.Parameter.ParameterType = reader["ParameterType"].ToString();
                det.Parameter.QualityDeviationLevel = reader["QualityDeviationLevel"].ToString();

                if (nFormulas.Count > 0)
                {
                     if (nFormulas.Any(x => x.RPN.RPN_Id == Int32.Parse(reader["RPN_Id"].ToString())))
                     {
                         nFormulas.First(x=>x.RPN.RPN_Id == Int32.Parse(reader["RPN_Id"].ToString())).RPN.RPNDetails.Add(det);
                     }
                     else
                     {
                         NumericFormulaDO nFormula = CreatingNumericFormulaDO(reader, det);
                         nFormulas.Add(nFormula);
                         //System.Diagnostics.Trace.WriteLine(nFormulas.Count.ToString());
                     }
                }
                else
                {
                     NumericFormulaDO nFormula = CreatingNumericFormulaDO(reader, det);
                     nFormulas.Add(nFormula);
                     //System.Diagnostics.Trace.WriteLine(nFormulas.Count.ToString());
                }
            }
        }
    }

    return nFormulas;
}

private static NumericFormulaDO CreatingNumericFormulaDO(SqlDataReader reader, RPNDetailsDO det)
{
    var nFormula = new NumericFormulaDO();
    nFormula.CalculateDuringLoad = Boolean.Parse(reader["CalculateDuringLoad"].ToString());
    nFormula.NumericFormula_Id = Int32.Parse(reader["NumericFormula_Id"].ToString());
    nFormula.RPN.RPN_Id = Int32.Parse(reader["RPN_Id"].ToString());
    nFormula.RPN.Formula = reader["Formula"].ToString();
    nFormula.Unit.Name = reader["Name"].ToString();

    if (reader["Unit_Id"] != DBNull.Value)
    {
        nFormula.Unit.Unit_Id = Int32.Parse(reader["Unit_Id"].ToString());
        nFormula.Unit.UnitType.Type = reader["Type"].ToString();
        nFormula.Unit.UnitType.UnitType_Id = Int32.Parse(reader["UnitType_Id"].ToString());
    }
    nFormula.RPN.RPNDetails.Add(det);
    return nFormula;
}
公共静态列表SelectAllNumericFormulas()
{
var nFormulas=新列表();
字符串queryString=@”
挑选*
从数值公式nf
u.Unit\u Id=nf.Unit\u Id上的左连接单元u
在ut.UNITYPE\u Id=u.UNITYPE\u Id上左连接UNITYPE ut
在r.RPN\u Id=nf.RPN\u Id上加入RPN r
在rd.RPN\u Id=r.RPN\u Id上加入RPNDetails rd

在PAR.PerrimerIdID= R.PosierStID ID上加入参数PAR.No.FrimeFrimaAID ID> P>LINQ to SQL消耗ADO.NET并具有额外开销,所以不:除非它不做相同的工作,否则它不应该更快。有提到通过序号与名称的访问,但是坦率地说,影响微秒,而不是秒。它不能解释MAGN的顺序。气候变化

回答这个问题的唯一方法是跟踪LINQ to SQL正在做什么。幸运的是,这很简单-您可以执行以下操作:

dbContext.Log = Console.Out;
将TSQL写入控制台。然后有两个选项:

  • 您发现TSQL并没有做同样的事情(可能它没有急于加载)
  • 您发现TSQL是有效的(=做同样的事情),但是有一个更好的计划-在这种情况下…“借用”它:p

  • 一旦有了要比较的TSQL,就要并排测试,这样就可以测试相同的工作了"-消除了将读卡器映射到对象的枯燥乏味的工作,但进行了非常优化。

    基于上述注释重写了ADO.NET代码,这应该快得多。使用序数值而不是列名,以及以与查询中完全相同的顺序读取字段,仍然可以提高效率,但这些都是微观优化美国

    我还删除了几个重复的.Y,作为Parse(ToString)路由效率非常低,在使用不同语言运行的系统运行时可能会导致非常奇怪的问题。当涉及十进制、浮点或双精度时,在进行这些转换时,也有可能会丢失数据,因为并非所有值都能正确转换为字符串(或无法往返)

    公共静态列表SelectAllNumericFormulas()
    {
    var nFormulas=新字典();
    字符串queryString=@”
    挑选*
    从数值公式nf
    u.Unit\u Id=nf.Unit\u Id上的左连接单元u
    在ut.UNITYPE\u Id=u.UNITYPE\u Id上左连接UNITYPE ut
    在r.RPN\u Id=nf.RPN\u Id上加入RPN r
    在rd.RPN\u Id=r.RPN\u Id上加入RPNDetails rd
    
    在PAR.PerrimerIdID=R.MealersIdID上加入参数PAR,其中NF.Nig.FrimeFrimaAIDID可以发布您的ADO代码,这样我们就可以看到您是否做了什么错事?您实际上是使用LINQtoSQL检索数据,还是刚刚构造了一个查询,当执行时,它将检索数据(延迟执行)。?如果您可以发布所有查询代码,比较ADO.NET、LINQ到SQL和NHibernate会很有帮助。使用ADO.NET execute reader和linqtosql做的事情不一样。使用reader时,如果(nFormulas.Count>0),则整个
    part…可能需要一些时间…尝试修改您的查询字符串以达到相同的效果。@PiotrCzarnecki-您的ADO代码效率极低。请给出以下建议:由于基于序号的查找比命名查找效率更高,因此在循环中调用GetOrdinal效率较低。通过每年调用一次GetOrdinal来节省时间d将结果分配给一个整数变量,以便在循环中使用。感谢您的响应,我借用了linq生成的查询,是的,您是对的,这个查询做的事情不完全相同。但当我执行该查询和我以前的ADO查询时,linq生成的查询时间要长很多倍。我理解这种情况,因为执行查询ybe在ADO中速度更快,但整个映射过程(使用读取器迭代和赋值)非常耗时。对于简单的选择(以及映射“算法”),ADO速度更快(无需加入等)。我仍然想知道为什么Linq到SQL的映射速度如此之快。正如我之前所说的,我知道我的ADO代码可能不太好,但这个示例中的Linq比NHibernate快得多。还有其他想法吗?@Piotr哦,我希望它能映射得更快。事实上,它没有-这正是我们(堆栈交换)编写“dapper”的原因“.LINQ to SQL在具体化方面相对来说非常慢。是的,NHibernate在这方面也很慢(相对而言)(这种灵活/抽象模型的“税”)。大家好,我分析了ADO应用程序,分析器显示87%的时间花在.Any()方法上,10%的时间花在.First()上方法。所以我认为这就是它花费如此长时间的原因。但在复杂的查询结果中,在读卡器上迭代时,很难忽略一些附加条件、内部循环或内部linq to objects表达式。我尝试使用附加嵌套连接和两个查询字符串的选项来避免linq to objects meth
    IQueryable<NumericFormulaDO> nFormulas =
        session.Query<NumericFormulaDO>()
            .Where(x=>x.NumericFormula_Id <=10000);
    
    List<NumericFormulaDO> nForList =
        new List<NumericFormulaDO>();
    
    nForList = nFormulas.ToList<NumericFormulaDO>();
    
    dbContext.Log = Console.Out;
    
    public static List<NumericFormulaDO> SelectAllNumericFormulas()
    {
        var nFormulas = new Dictionary<int, NumericFormulaDO>();
    
        string queryString = @"
        SELECT *
        FROM    NumericFormula nf 
                Left Join Unit u on u.Unit_Id = nf.Unit_Id 
                Left Join UnitType ut on ut.UnitType_Id = u.UnitType_Id 
                Join RPN r on r.RPN_Id = nf.RPN_Id 
                Join RPNDetails rd on rd.RPN_Id = r.RPN_Id 
                Join Parameter par on par.Parameter_Id = rd.Parameter_Id where nf.NumericFormula_Id<=10000";
    
        using (var connection = new SqlConnection(connectionString))
        {  
            connection.Open();
            using (var command = new SqlCommand(queryString, connection));
            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    var det = new RPNDetailsDO();
                    det.RPNDetails_Id = (int) reader.GetValue("RPNDetails_Id");
                    det.RPN_Id = (int) reader.GetValue("RPN_Id");
                    det.Identifier = (string) reader.GetValue("Identifier");
                    det.Parameter.Architecture = (string)reader.GetValue("Architecture");
                    det.Parameter.Code = (string)reader.GetValue("Code");
                    det.Parameter.Description = (string)reader.GetValue("Description");
                    det.Parameter.Parameter_Id = (int) reader.GetValue("Parameter_Id");
                    det.Parameter.ParameterType = (string)reader.GetValue("ParameterType");
                    det.Parameter.QualityDeviationLevel = (string)reader.GetValue("QualityDeviationLevel");
    
                    NumericFormulaDO parent = null;
                    if (!nFormulas.TryGetValue((int)reader.GetValue("RPN_Id"), out parent)
                    {
                        parent = CreatingNumericFormulaDO(reader, det);
                        nFormulas.Add(parent.RPN.RPNID, parent);
                    }
                    else
                    {
                        parent.RPN.RPNDetails.Add(det);
                    }
                }
            }
        }
    
        return nFormulas.Values.ToList();
    }