已经有一个与此Connection关联的开放DataReader,必须先关闭它。 C#

时间:2013-07-19 10:49:13

标签: c# asp.net

我在控制器上收到此错误

System.Data.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> MySql.Data.MySqlClient.MySqlException: There is already an open DataReader associated with this Connection which must be closed first.
   at MySql.Data.MySqlClient.MySqlCommand.CheckState()
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
   at MySql.Data.Entity.EFMySqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
   --- End of inner exception stack trace ---
   at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
   at System.Data.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)
   at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
   at System.Data.Objects.ObjectQuery`1.Execute(MergeOption mergeOption)
   at System.Data.Objects.DataClasses.EntityReference`1.Load(MergeOption mergeOption)
   at System.Data.Objects.DataClasses.RelatedEnd.Load()
   at System.Data.Objects.DataClasses.RelatedEnd.DeferredLoad()
   at System.Data.Objects.DataClasses.EntityReference`1.get_Value()
   at Timee.fingerprint.get_employee() in C:\Users\MyNameDesktop\Time\Timee\AModel.Designer.cs:line 2234
   at Timee.BundyForm.verificationControl_OnComplete(Object Control, FeatureSet FeatureSet, EventHandlerStatus& EventHandlerStatus) in C:\Users\MyName\Desktop\Time      \Timee\BundyForm.cs:line 82
   at DPFP.Gui.Verification.VerificationControl.<>c__DisplayClass2.<relay_OnComplete>b__0()

控制器:

 void verificationControl_OnComplete(object Control, DPFP.FeatureSet FeatureSet, ref DPFP.Gui.EventHandlerStatus EventHandlerStatus)
    {
        clearInfoBoxTimer.Stop();

        DateTime entryTime = DateTime.Now;

        DPFP.Verification.Verification ver = new DPFP.Verification.Verification();
        DPFP.Verification.Verification.Result res = new DPFP.Verification.Verification.Result();

        employee employees = null;
        foreach (fingerprint fingerPrint in this.db.fingerprints)
        {
            DPFP.Template template = new DPFP.Template();
            template.DeSerialize(fingerPrint.data);
            ver.Verify(FeatureSet, template, ref res); 
            if (res.Verified)
            {
                employees = fingerPrint.employee; //Im GETTING AN ERROR HERE
                break;
            }
        }
     }

根据我阅读的一些论坛,我必须将multipleactiveresultsets=True;添加到我的webconfig中。但在我的情况下,它不适用,因为我正在使用不支持它的MYSQL。有没有其他方法可以使这项工作?请帮帮我们,谢谢。

验证模型

// Summary:
//     Performs the system function of fingerprint verification, which is a one-to-one
//     comparison of a fingerprint feature set with a fingerprint template produced
//     at enrollment that returns a decision of match or non-match.
public class Verification
{
    // Summary:
    //     Use this value to specify the default FAR threshold
    public const int ProbabilityNotSet = -1;

    // Summary:
    //     Initializes a new instance of the Verification class for comparing a fingerprint
    //     feature set with a fingerprint template using the default value of the false
    //     accept rate (FAR)
    public Verification();
    //
    // Summary:
    //     Initializes a new instance of the Verification class for comparing a fingerprint
    //     feature set with a fingerprint template and assigns the value of the FAR
    //
    // Parameters:
    //   FARRequested:
    //     Value of the requested FAR
    public Verification(int FARRequested);

    // Summary:
    //     Returns or assigns the requested false accept rate (FAR)
    public int FARRequested { get; set; }

    // Summary:
    //     Performs fingerprint verification and returns the comparison decision based
    //     on the default FAR threshold
    //
    // Parameters:
    //   FeatureSet:
    //     A DPFP.FeatureSet object
    //
    //   Template:
    //     A DPFP.Template object
    //
    // Returns:
    //     Verification result object
    public static Verification.Result Verify(FeatureSet FeatureSet, Template Template);
    //
    // Summary:
    //     Performs fingerprint verification and returns the comparison decision based
    //     on the specified FAR threshold
    //
    // Parameters:
    //   FeatureSet:
    //     A DPFP.FeatureSet object
    //
    //   Template:
    //     A DPFP.Template object
    //
    //   FARRequested:
    //     False Accept probability threshold or ProbabilityNotSet to use the default
    //     threshold
    //
    // Returns:
    //     Verification result object
    public static Verification.Result Verify(FeatureSet FeatureSet, Template Template, int FARRequested);
    //
    // Summary:
    //     Performs the system function of fingerprint verification and specifies a
    //     comparison decision based on the FAR set by the FARRequested property
    //
    // Parameters:
    //   FeatureSet:
    //     A DPFP.FeatureSet object
    //
    //   Template:
    //     A DPFP.Template object
    //
    //   Result:
    //     A DPFP.Verification.Result object
    public void Verify(FeatureSet FeatureSet, Template Template, ref Verification.Result Result);

    // Summary:
    //     Represents the results of a fingerprint verification operation.
    public class Result
    {
        // Summary:
        //     Default c-tor
        public Result();

        // Summary:
        //     Returns or assigns the value of the achieved FAR for a comparison operation.
        public int FARAchieved { get; set; }
        //
        // Summary:
        //     Returns or assigns the comparison decision, which indicates whether the comparison
        //     of a fingerprint feature set and a fingerprint template resulted in a decision
        //     of match or non-match. This decision is based on the value of the FARRequested
        //     property
        public bool Verified { get; set; }
    }
}

6 个答案:

答案 0 :(得分:1)

以下代码有帮助吗?

foreach (fingerprint fingerPrint in this.db.fingerprints)
{
    using(fingerprint)
    {
        DPFP.Template template = new DPFP.Template();
        template.DeSerialize(fingerPrint.data);
        ver.Verify(FeatureSet, template, ref res); 
        if (res.Verified)
        {
            employees = fingerPrint.employee; //Im GETTING AN ERROR HERE
            break;
        }
    }
}

答案 1 :(得分:1)

您无法在datareader中打开datareader。 (当已有打开的阅读器时,通常在嵌套循环中,您无法打开阅读器。)

作为一家公司,我们过去曾经遇到过这个问题。经过多次调查,为了我们的目的,我们决定重新考虑如何构建数据连接。

首先必须关闭打开的阅读器,然后打开下一个阅读器。因此,我们继续编写更面向对象的代码,使用类对象作为顶级循环的“存储”,并使用我们需要的数据填充该对象。

关闭阅读器。

逐步浏览临时对象并打开阅读器以获取更多数据。

洗涤,冲洗,重复。

这对我们来说效果很好。

P.S,您还可以通过更好地利用表连接来消除嵌套的读取循环。

答案 2 :(得分:1)

什么数据类型是res?什么数据类型是指纹?

您可能需要为结果提供更多上下文,但听起来您应该返回数据集/ dataadapter而不是返回ADO.NET连接。 fingerPrint.employee可能使用相同的底层连接,但您没有关闭第一个读取器,因此错误消息。

如果实施此策略,它将允许您与底层数据库实例分离。

因此,您的数据库层将在内部使用IDataReader,然后返回上层可以迭代的DataSet或DataAdapter,而不必担心打开数据库连接。

答案 3 :(得分:0)

您需要在connectionstring中启用multipleActive结果集。

将“MultipleActiveResultSets = True”添加到您的连接字符串。

请参阅以下链接。 http://www.dotnetjalps.com/2013/06/Entity-Framework-There-is-already-an-open-DataReader-associated-with-this-Command.html

答案 4 :(得分:0)

我现在能够找到自己问题的答案。这是我的工作解决方案

 void verificationControl_OnComplete(object Control, DPFP.FeatureSet FeatureSet, ref DPFP.Gui.EventHandlerStatus EventHandlerStatus)
    {
        clearInfoBoxTimer.Stop();

        DateTime entryTime = DateTime.Now;

        DPFP.Verification.Verification ver = new DPFP.Verification.Verification();
        DPFP.Verification.Verification.Result res = new DPFP.Verification.Verification.Result();

        employee employees = null;
        foreach (fingerprint fingerPrint in this.db.fingerprints)
        {
            DPFP.Template template = new DPFP.Template();
            template.DeSerialize(fingerPrint.data);
            ver.Verify(FeatureSet, template, ref res); 
            if (res.Verified)
            {
                db.Connection.Close(); //I close the connection first
                db.Connection.Open(); // then I open it again

                employees = fingerPrint.employee; 
                break;
            }
        }
     }

基于这里的人们和我在某些论坛上的建议,我需要首先关闭打开的阅读器,然后再打开它。我花了很多时间思考如何做到这一点,最后我现在能够找到一个。这就是我如何以最简单的方式解决我的问题,我不知道是否还有其他解决方案。但至少这解决了我的问题,我仍然非常感谢在这里尽力帮助我的人们。感谢你们。 :)

答案 5 :(得分:0)

当您使用foreach迭代指纹时,它会保持连接打开。一种解决方案是在指纹上调用ToList(),这将获得所有指纹并将它们放入列表中,然后关闭连接。然后,您可以使用foreach遍历列表并对列表中的每个项执行其他查询。例如:

foreach (fingerprint fingerPrint in this.db.fingerprints.ToList())

这个问题还有其他一些答案:

Entity Framework: There is already an open DataReader associated with this Command