2012-12-11 14 views
12

Im przy użyciu Entity Framework 4.3 kod najpierw do wywołania procedury przechowywanej sposób wzywam procedura przechowywana jest tak:Dlaczego Entity Framework rzuca wyjątek podczas zmiany kolejności SqlParameter?

var parameters = new[] 
{ 
    new SqlParameter("member", 1), 
    **new SqlParameter("Code","0165210662660001"),** 
    new SqlParameter("PageSize", 1), 
    new SqlParameter("PageNumber",1) 
}; 

var result = context.Database.SqlQuery<resultClass>(
    "mySpName @member, @Code, @PageSize,@PageNumber" parameters).ToList(); 

ona pobiera wykonywane na SqlServer i uzyskać wynik.

Ale jeśli mogę zmienić kolejność paramaters takiego:

var result = context.Database.SqlQuery<resultClass>("mySpName @Code, @member,@PageSize,@PageNumber" parameters).ToList(); 

var parameters = new[] 
{ 
    **new SqlParameter("Code","0165210662660001"),** 
    new SqlParameter("Member", 1), 
    new SqlParameter("PageSize", 1), 
    new SqlParameter("PageNumber",1) 
}; 

Mam błąd podobny do tego:

Error converting data type nvarchar to int 

procedura przechowywana jest tak:

ALTER PROCEDURE [c].[mySpName] 
    @Member INT , 
    @Code VARCHAR (50) , 
    @PageSize INT , 
    @PageNumber INT 
AS 

Dlaczego otrzymuję to zamówienie? Czy ważne jest utrzymanie kolejności parametrów? Co mogę zrobić, aby móc wywołać procedurę przechowywaną bez obawy o kolejność parametrów?

============ znajdę obejście i działa idealnie ============

public class blahContext<T> 
{ 
    int i = 0; 
    public IEnumerable<T> ExecuteStoreQuery(string SPname, SqlParameter[] parameters) 
    { 

     using (var context = new CADAContext()) 
     { 


      string para = string.Join(", ", (from p in parameters 
              where !"NULL".Equals(p.Value) 
              select string.Concat(new object[] { "@", p.ParameterName, "={", this.i++, "}" })).ToList<string>()); 

      object[] x = (from p in parameters 
          where !"NULL".Equals(p.Value) 
          select p.Value).ToArray<object>(); 

      return context.Database.SqlQuery<T>(SPname + " " + para, x).ToList(); 

     } 
    } 
+0

To dlatego, że zmieniłeś kolejność parametrów podczas wywoływania SP - zobacz moją odpowiedź poniżej w celu wyjaśnienia. –

Odpowiedz

6

To nie ze względu na Kolejność parametrów w obiekcie parametrów - ponieważ w drugim fragmencie kodu wyraźnie podajemy wartość @Code jako pierwszy parametr, gdy SP oczekuje wartości Member INT.

var result = context.Database.SqlQuery<resultClass>("mySpName @Code, @member,@PageSize,@PageNumber" parameters).ToList(); 

... jesteś przejazdem w "0165210662660001" jako pierwszy parametr i konwersja do INT zawodzi.

Kolejność parametrów w obiekcie parametrów jest nieistotna, ponieważ EF (w rzeczywistości ADO.NET) zmapuje te parametry do wartości @parametername w ciągu zapytania. Tak więc new SqlParameter("Code","0165210662660001") zostanie zamapowany na pozycję @Code w zapytaniu - w której drugi kod jest faktycznie pozycją dla wartości elementu zgodnie z oczekiwaniami SP.

jednak ... można wykonać SP pomocą nazwanych parametrów, jak również i w tym przypadku można przekazać parametry do SP w dowolnej kolejności jak poniżej:

db.Database.SqlQuery<resultClass>("mySpName [email protected],[email protected],[email protected],[email protected]", parameters).ToList(); 

Widać, że nie jestem przekazując parametry do SP w kolejności, w jakiej zostały zdefiniowane [przez SP], ale ponieważ zostały one nazwane, nie muszę się przejmować.

Aby zapoznać się z różnymi sposobami przekazywania parametrów, zobacz: To na przykład Answer.

+0

to nie jest obejście problemu, dodałem obejście, edytując pytanie: – 1AmirJalali

+0

Wygląda na to, że kolejność parametrów absolutnie ma znaczenie ... E.g. jeśli SP ma parametry w tej kolejności: A, B, C - wówczas odwzorowuje pierwsze 3 parametry na A, B, C. – mmcrae

+0

Nie, jeśli używałeś nazwanych parametrów podczas przekazywania wartości argumentów. na przykład. exec mySpName PageNumber = 1, Code = 2, PageSize = 3, Member = 'alpha' –

Powiązane problemy