2010-02-07 4 views
3

J'ai une procédure stockée que j'appelle via Entity Framework.Mêmes données retournées par linq pour 2 exécutions différentes d'une procédure stockée?

La procédure stockée a 2 paramètres de date. Je fournis un argument différent dans les 2 fois que j'appelle la procédure stockée. J'ai vérifié en utilisant SQL Profiler que la procédure stockée est appelée correctement et renvoyant les résultats corrects.

Lorsque j'appelle ma méthode la deuxième fois avec des arguments différents, même si la procédure stockée ramène les résultats corrects, la table créée contient les mêmes données que la première fois que je l'ai appelée.

dtStart = 01/08/2009 
dtEnd = 31/08/2009 

public List<dataRecord> GetData(DateTime dtStart, DateTime dtEnd) 
{ 
    var tbl = from t in db.SP(dtStart, dtEnd)      
         select t; 
    return tbl.ToList();    
} 

GetData((new DateTime(2009, 8, 1), new DateTime(2009, 8, 31)) 
// tbl.field1 value = 45450 - CORRECT 

GetData(new DateTime(2009, 7, 1), new DateTime(2009, 7, 31)) 
// tbl.field1 value = 45450 - WRONG 27456 expected 

Est-ce un cas de Entity Framework étant intelligent et la mise en cache? Je ne vois pas pourquoi il mettrait ce cache en cache car il a exécuté deux fois la procédure stockée.

Dois-je faire quelque chose pour fermer tbl?

  • en utilisant Visual Studio 2008 + Entity Framework.
  • Je reçois également le message "requête ne peut être énumérée plus d'une fois" quelques fois de temps en temps, je ne suis pas sûr si cela est pertinent?

CODE COMPLET COTATION

namespace ProfileDataService 
{ 
    public partial class DataService 
    { 

     public static List<MeterTotalConsumpRecord> GetTotalAllTimesConsumption(DateTime dtStart, DateTime dtEnd, EUtilityGroup ug, int nMeterSelectionType, int nCustomerID, 
               int nUserID, string strSelection, bool bClosedLocations, bool bDisposedLocations) 
     {  
      dbChildDataContext db = DBManager.ChildDataConext(nCustomerID); 

      var tbl = from t in db.GetTotalConsumptionByMeter(dtStart, dtEnd, (int) ug, nMeterSelectionType, nCustomerID, nUserID, strSelection, bClosedLocations, bDisposedLocations, 1)      
         select t; 

      return tbl.ToList();    
     } 
} 
} 

/// CALLER 

List<MeterTotalConsumpRecord> _P1Totals; 
List<MeterTotalConsumpRecord> _P2Totals; 

public void LoadData(int nUserID, int nCustomerID, ELocationSelectionMethod locationSelectionMethod, string strLocations, bool bIncludeClosedLocations, bool bIncludeDisposedLocations, 
      DateTime dtStart, DateTime dtEnd, ReportsBusinessLogic.Lists.EPeriodType durMainPeriodType, ReportsBusinessLogic.Lists.EPeriodType durCompareToPeriodType, ReportsBusinessLogic.Lists.EIncreaseReportType rptType, 
      bool bIncludeDecreases) 
{ 

    ///Code for setting properties using parameters..   

    _P2Totals = ProfileDataService.DataService.GetTotalAllTimesConsumption(_P2StartDate, _P2EndDate, EUtilityGroup.Electricity, 1, nCustomerID, nUserID, strLocations, 
       bIncludeClosedLocations, bIncludeDisposedLocations); 

    _P1Totals = ProfileDataService.DataService.GetTotalAllTimesConsumption(_StartDate, _EndDate, EUtilityGroup.Electricity, 1, nCustomerID, nUserID, strLocations, 
       bIncludeClosedLocations, bIncludeDisposedLocations); 


    PopulateLines() //This fills up a list of objects with information for my report ready for the totals to be added 

    PopulateTotals(_P1Totals, 1); 
    PopulateTotals(_P2Totals, 2); 

} 


void PopulateTotals(List<MeterTotalConsumpRecord> objTotals, int nPeriod) 
{ 
     MeterTotalConsumpRecord objMeterConsumption = null; 

     foreach (IncreaseReportDataRecord objLine in _Lines) 
     { 
      objMeterConsumption = objTotals.Find(delegate(MeterTotalConsumpRecord t) { return t.MeterID == objLine.MeterID; }); 

      if (objMeterConsumption != null) 
      { 
       if (nPeriod == 1) 
       { 
        objLine.P1Consumption = (double)objMeterConsumption.Consumption; 
       } 
       else 
       { 
        objLine.P2Consumption = (double)objMeterConsumption.Consumption; 
       } 

       objMeterConsumption = null; 
      } 
     } 
    } 
} 
+0

J'ai essayé de mon mieux pour modifier, mais honnêtement, je fais une vraiment difficile de comprendre ce qui se passe ici. Vous pourriez vouloir afficher un exemple de code de travail réel au lieu de morceaux et morceaux ici et là. – Aaronaught

+0

Merci de l'avoir bien édité! Quand j'appelle GetData pour Août 2009, je reçois le numéro que je me attends - 45450 Quand j'appelle GetData pour Juillet 2009, je également obtenir 45450. Ceci est faux, je me attends à obtenir 27456 Le message d'erreur exact que je Je reçois occasionnellement System.InvalidOperationException: Le résultat d'une requête ne peut pas être énuméré plus d'une fois. Vous ne savez pas si cela a quelque chose à voir avec ça? – Paul

+0

Paul, cela n'aide pas, vous venez de répéter les informations que vous nous avez déjà donné. D'une part, 'GetData' renvoie une ** liste **, et vous nous dites le résultat d'un seul enregistrement, ce qui n'a pas de sens. Et il n'y a pas assez de code ici pour essayer de retrouver la source de ce message d'erreur - cela arrive quand vous essayez de réutiliser les résultats d'une requête. S'il vous plait, comme indiqué précédemment, postez un exemple de code * complet * qui reproduit votre problème. – Aaronaught

Répondre

0

Tenir compte changer la classe DataService pour ressembler à ceci:

public partial class DataService 
{ 
    public List<MeterTotalConsumpRecord> 
         GetTotalAllTimesConsumption(SearchCriteria sc) 
    {  
     var db = new dbChildDataContext(); // new every time, just in this test case. 

     var totalConsumption = db.GetTotalConsumptionByMeter(sc.DtStart, 
                  sc.DtEnd, 
                  sc.ug, 
                  sc.MeterSelectionType, 
                  sc.CustomerID, 
                  sc.UserID, 
                  sc.Selection, 
                  sc.ClosedLocations, 
                  sc.DisposedLocations, 1) 
           .ToList();      

     //inspect how many results are returned. 
     int rowCount = totalConsumption.Count; 


     return totalConsumption; 

    } 
} 


//use objects to pass between classes 
public class SearchCriteria 
{ 
    public DateTime DtStart {get;set;} 
    public DateTime DtEnd {get;set;} 
    public int ug {get;set;} 
    public int MeterSelectionType {get;set;} 
    public int CustomerID {get;set;} 
    public int UserID {get;set;} 
    public string Selection {get;set;} 
    public bool ClosedLocations {get;set;} 
    public bool DisposedLocations {get;set;} 
} 
+0

Merci, cela fonctionne mais n'y a-t-il aucun moyen d'éviter de créer un nouveau contexte? – Paul

Questions connexes