Pytanie Dlaczego Entity Framework rzuca wyjątek podczas zmiany zlecenia SqlParameter?


Im using entity framework 4.3 kod first dla wywoływania procedury przechowywanej sposób w jaki wywołuję procedura przechowywana jest tak:

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();

Wykonuje się go na SqlServer i otrzymuję wynik.

Ale jeśli zmienię kolejność parametrów w ten sposób:

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 w następujący sposób:

 Error converting data type nvarchar to int

Procedura przechowywana jest następująca:

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

Dlaczego otrzymuję to zamówienie? Czy ważne jest utrzymywanie porządku parametrów? Co mogę zrobić, aby wywołać procedurę przechowywaną bez obaw o kolejność parametrów?

============ znajduję 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();

        }
    }

12
2017-12-11 08:46


pochodzenie


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


Odpowiedzi:


Nie jest to spowodowane kolejnością parametrów w obiekcie parametrów - dzieje się tak dlatego, że w drugim fragmencie kodu wyraźnie podajesz parametr @Code wartość jako pierwszy parametr, gdy SP oczekuje a Member INT wartość.

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

... przechodzisz "0165210662660001" jako pierwszy parametr i konwersja na INT nie działa.

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

Jednak ... możesz wykonać SP używając nazwanych parametrów, w takim przypadku możesz przekazać parametry do SP w dowolnej kolejności, jak poniżej:

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

Widzisz, że nie przekazuję parametrów do SP w kolejności, w jakiej zostały zdefiniowane [przez SP], ale ponieważ są one nazwane, nie muszę się przejmować.

Różne sposoby przekazywania parametrów zobacz: To Odpowiedź na kilka dobrych przykładów.


6
2017-12-19 14:25



nie jest to obejście, dodałem obejście, edytując pytanie - 1AmirJalali
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 - wtedy odwzorowuje pierwsze 3 parametry na A, B, C. - mmcrae
Nie, jeśli użyłeś nazwanych parametrów podczas przekazywania wartości argumentów. na przykład. exec mySpName PageNumber = 1, Code = 2, PageSize = 3, Member = 'alpha' - Quinton Bernhardt