संग्रहीत कार्यविधि के साथ DbContext.Database.SqlQuery <Telement> (sql, params) का उपयोग कैसे करें? EF कोड पहले CTP5


250

मेरे पास एक संग्रहीत कार्यविधि है जिसमें तीन पैरामीटर हैं और मैं परिणामों को वापस करने के लिए निम्नलिखित का उपयोग करने की कोशिश कर रहा हूं:

context.Database.SqlQuery<myEntityType>("mySpName", param1, param2, param3);

पहले तो मैंने SqlParameterवस्तुओं को परम के रूप में उपयोग करने की कोशिश की लेकिन यह काम नहीं किया और SqlExceptionनिम्नलिखित संदेश के साथ फेंक दिया :

प्रक्रिया या कार्य 'mySpName' पैरामीटर '@ param1' की अपेक्षा करता है, जिसकी आपूर्ति नहीं की गई थी।

तो मेरा सवाल यह है कि आप इस विधि का उपयोग कैसे कर सकते हैं एक संग्रहीत प्रक्रिया के साथ जो मापदंडों की अपेक्षा करता है?

धन्यवाद।


SQL सर्वर के किस संस्करण का आप उपयोग कर रहे हैं? मुझे कोड के साथ समस्या हो रही है जो 2008 में कॉम्पिटिटर (90) मोड पर काम करता है, लेकिन जब मैं इसे 2005 के खिलाफ चलाता हूं तो यह सिंटैक्स त्रुटि के साथ विफल हो जाता है।
नमस्ते

4
@ सलाम - मेरे पास वही मुद्दा w / SQL 2005 था। संग्रहीत कार्यविधि नाम से पहले "EXEC" जोड़ें। मैंने इस जानकारी को भविष्य के संदर्भ के लिए यहां पोस्ट किया है: stackoverflow.com/questions/6403930/…
Dan Mork

जवाबों:


389

आपको निम्न तरीके से SqlParameter इंस्टेंस की आपूर्ति करनी चाहिए:

context.Database.SqlQuery<myEntityType>(
    "mySpName @param1, @param2, @param3",
    new SqlParameter("param1", param1),
    new SqlParameter("param2", param2),
    new SqlParameter("param3", param3)
);

3
आप इस विधि को अशक्त प्रकारों के साथ कैसे काम करेंगे? मैंने इसे अशक्त दशमलव के साथ आज़माया, लेकिन जब दशमलव अशक्त होता है तो मुझे त्रुटियां मिलती हैं कहती हैं कि पैरामीटर गायब है। हालाँकि, नीचे वर्णित विधि @DanMork काम करती है।
पॉल जॉनसन

2
क्या DbNull.Valueनल की बजाय पास करने से समस्या हल हो जाती है?
एलिरेज़ा

29
आप संदर्भ में SqlParameter का उपयोग करने से बचने के लिए \ @ p # सिंटैक्स का भी उपयोग कर सकते हैं। Database.SqlQuery <myEntityType ("mySpName \ @ p0, \ @ p1, \ @ P2", param1, param2, par3)। स्रोत: msdn.microsoft.com/en-US/data/jj592907 । (नोट: उपयोगकर्ता सूचनाओं से बचने के लिए \ @ का उपयोग करना चाहिए, बैकस्लैश के बिना पढ़ा जाना चाहिए।)
मार्को

3
यदि आप DateTime पैरामीटर का उपयोग कर रहे हैं, तो आपको केवल नाम और मान ही नहीं, पैरामीटर प्रकार भी निर्दिष्ट करने की आवश्यकता है। उदाहरण के लिए: dbContext.Database.SqlQuery <Invoice> ("spGetInvoices @dateFrom, @dateTo", नया SqlParameter {ParameterName = "date_rom", SqlDbType = SqlDbType.DateTime, मान = startDate}, "StartDate}, नया"। SqlDbType = SqlDbType.DateTime, Value = endDate}); एक अन्य महत्वपूर्ण बात मापदंडों के आदेश का सम्मान करना है।
फ्रांसिस्को गोल्डनस्टीन

क्या आप कृपया जाँच कर सकते हैं कि मैं क्या गलत कर रहा हूँ, मैंने आपके दिशानिर्देशों का पालन किया है लेकिन सभी stackoverflow.com/questions/27926598/…
विषाक्त

129

इसके अलावा, आप "sql" पैरामीटर का उपयोग प्रारूप विनिर्देशक के रूप में कर सकते हैं:

context.Database.SqlQuery<MyEntityType>("mySpName @param1 = {0}", param1)

इसको अप-वोट करना था। हालांकि यह उत्तर के रूप में स्वीकार नहीं किया गया था, इसका उत्तर के रूप में चयनित की तुलना में समाधान लिखना बहुत आसान है।
निक्कोली

10
यह वाक्य रचना मुझे थोड़ा चिंतित करती है। क्या यह एसक्यूएल इंजेक्शन के लिए अतिसंवेदनशील होगा? मुझे लगता है कि EF "EXEC mySpName @ Param1 =" चला रहा है, और क्या "x 'GO [दुर्भावनापूर्ण स्क्रिप्ट] भेजना और कुछ समस्याओं का कारण होगा?
टॉम हॉलैडे

10
@TomHalladay में SQL इंजेक्शन का कोई खतरा नहीं है - विधि अभी भी उनके प्रकार के आधार पर मापदंडों को कोट करेगी और बच जाएगी, @ स्टाइल पारम्स के समान। तो एक स्ट्रिंग पैरामीटर के लिए आप अपने बयान में उद्धरण के बिना "SELECT * FROM उपयोगकर्ताओं से ईमेल = {0}" का उपयोग करेंगे।
रॉस मैकनाब

मेरे मामले में हमारे पास SP के लिए बहुत सारे वैकल्पिक पैरामीटर हैं और SqlParameters के साथ कॉल पर काम नहीं किया है, लेकिन यह प्रारूप चाल है, बस शुरुआत में 'EXEC' जोड़ना था। धन्यवाद।
ओनूर टॉपल

1
यह उत्तर उपयोगी है यदि आपको मापदंडों को वैकल्पिक मापदंडों के साथ किसी निर्दिष्ट पर निर्दिष्ट करना है। उदाहरण है कि काम नहीं करता है: ProcName @optionalParam1 = @opVal1, @optionalParam2 = @opVal2 उदाहरण है कि काम करता है:ProcName @optionalParam1 = {0}, @optionalParam2 = {1}
गैरीसन नाइस

72

यह समाधान SQL Server 2005 के लिए (केवल) है

आप लोग जीवन रक्षक हैं, लेकिन जैसा कि @Dan Mork ने कहा, आपको मिश्रण में EXEC जोड़ने की आवश्यकता है। क्या मुझे ट्रिपिंग कर रहा था:

  • प्रोक नाम से पहले 'EXEC'
  • परम के बीच में कॉमस
  • परम परिभाषाओं पर '@' काट कर (निश्चित नहीं है कि बिट की आवश्यकता है)।

:

context.Database.SqlQuery<EntityType>(
    "EXEC ProcName @param1, @param2", 
    new SqlParameter("param1", param1), 
    new SqlParameter("param2", param2)
);

21
+1। न तो उच्च मतदान के जवाबों में शामिल हैं exec, लेकिन मैं पुष्टि कर सकता हूं कि अगर मैं इसे छोड़ देता हूं तो मुझे एक अपवाद मिलता है।
जॉर्डन ग्रे

धन्यवाद, मुझे एक त्रुटि मिल रही थी, अतिरिक्त EXEC जोड़ा और त्रुटि हो गई है। अजीब हिस्सा था अगर मैंने संदर्भ दिया। यह काम करता है, लेकिन अगर मैंने पैरामीटर जोड़ा तो यह तब तक काम नहीं करता जब तक मैंने EXEC कीवर्ड नहीं जोड़ा।
सोलेमाइड

2
FYI करें: मुझे execकीवर्ड की आवश्यकता नहीं है । Params पर @ को हटाने के लिए +1, जो मुझे हमेशा गड़बड़ करता है।
नाथन कोप

+1, मुझे EXEC याद आ रहा था और संदेश के साथ SqlException मिलती रही: 'procName' के पास गलत सिंटैक्स।
ए। मुरैना

1
@Ziggler आप 2005 या नए पर हैं? EXEC कीवर्ड मुख्य रूप से हम में से 2005 के खिलाफ जाने वालों के लिए एक मुद्दा रहा है।
टॉम हैलाडे

15
return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
new object[] { param1, param2, param3 });

// या

using(var context = new MyDataContext())
{
return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
new object[] { param1, param2, param3 }).ToList();
}

// या

using(var context = new MyDataContext())
{
object[] parameters =  { param1, param2, param3 };

return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
parameters).ToList();
}

// या

using(var context = new MyDataContext())
{  
return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
param1, param2, param3).ToList();
}

यह मेरे लिए असेंबली EntityFramework.dll, v4.4.0.0 के लिए काम कर रहा है
थुलसीराम

2
यदि आप (var संदर्भ = new MyDataContext ()) का उपयोग कर रहे हैं तो .TLList () अनिवार्य है।
थुलसीराम

मैंने यह पता लगाने के लिए कुछ अच्छा समय बिताया है कि .ToList () सही परिणाम सेट प्राप्त करने के लिए अनिवार्य है।
हलीम

8

अधिकांश उत्तर भंगुर हैं क्योंकि वे एसपी के मापदंडों के आदेश पर भरोसा करते हैं। बेहतर है कि स्टोर्ड प्रोक के पारेम्स का नाम लें और उन लोगों को पैरामीटर मान दें।

मापदंडों के आदेश के बारे में चिंता किए बिना, अपने एसपी को कॉल करते समय नामित नाम का उपयोग करने के लिए

ExecuteStoreQuery और ExecuteStoreCommand के साथ SQL सर्वर नामित मापदंडों का उपयोग करना

सबसे अच्छा तरीका बताता है। डैन मॉर्क के जवाब से बेहतर है यहां।

  • समतल तारों पर भरोसा नहीं करता है, और सपा में परिभाषित मापदंडों के आदेश पर निर्भर नहीं करता है।

उदाहरण के लिए:

var cmdText = "[DoStuff] @Name = @name_param, @Age = @age_param";
var sqlParams = new[]{
   new SqlParameter("name_param", "Josh"),
   new SqlParameter("age_param", 45)
};

context.Database.SqlQuery<myEntityType>(cmdText, sqlParams)

ऐसा लगता है कि "परम" एक आरक्षित कीवर्ड है, इसलिए मुझे नहीं लगता कि आप इसे इस तरह से उपयोग कर सकते हैं। अन्यथा यह मेरे लिए एक उपयोगी उत्तर था। धन्यवाद!
ooXei1sh

@ ooXei1sh - निश्चित, sqlParamsचर का उपयोग करते हुए
डॉन

आप आरक्षित शब्द का उपयोग करने के लिए @ के साथ इसे उपसर्ग कर सकते हैं , लेकिन आपको वास्तव में नहीं करना चाहिए
StingyJack

6
db.Database.SqlQuery<myEntityType>("exec GetNewSeqOfFoodServing @p0,@p1,@p2 ", foods_WEIGHT.NDB_No, HLP.CuntryID, HLP.ClientID).Single()

या

db.Database.SqlQuery<myEntityType>(
    "exec GetNewSeqOfFoodServing @param1, @param2", 
    new SqlParameter("param1", param1), 
    new SqlParameter("param2", param2)
);

या

var cmdText = "exec [DoStuff] @Name = @name_param, @Age = @age_param";
var @params = new[]{
   new SqlParameter("name_param", "Josh"),
   new SqlParameter("age_param", 45)
};

db.Database.SqlQuery<myEntityType>(cmdText, @params)

या

db.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
new object[] { param1, param2, param3 }).ToList();

3

मैं इस विधि का उपयोग करता हूं:

var results = this.Database.SqlQuery<yourEntity>("EXEC [ent].[GetNextExportJob] {0}", ProcessorID);

मुझे यह पसंद है क्योंकि मैं सिर्फ Guids और डेटासेट में छोड़ता हूं और SqlQuery मेरे लिए सभी स्वरूपण करता है।


1

@ तोमदले का जवाब इस उल्लेख के साथ सही है कि आप दुकानदारी को भी शून्य मानों के लिए जाँचते हैं और DbNullable को भेजते हैं, अगर परम नाल के रूप में अशक्त हैं, तो आपको एक अपवाद मिलेगा

पैरामीटर की गई क्वेरी '...' पैरामीटर '@parameterName' की अपेक्षा करती है, जिसकी आपूर्ति नहीं की गई थी।

कुछ इस तरह से मुझे मदद मिली

public static object GetDBNullOrValue<T>(this T val)
{
    bool isDbNull = true;
    Type t = typeof(T);

    if (Nullable.GetUnderlyingType(t) != null)
        isDbNull = EqualityComparer<T>.Default.Equals(default(T), val);
    else if (t.IsValueType)
        isDbNull = false;
    else
        isDbNull = val == null;

    return isDbNull ? DBNull.Value : (object) val;
}

(विधि का श्रेय https://stackoverflow.com/users/284240/tim-schmelter पर जाता है )

फिर इसका उपयोग करें जैसे:

new SqlParameter("@parameterName", parameter.GetValueOrDbNull())

या एक और समाधान, अधिक सरल, लेकिन सामान्य नहीं होगा:

new SqlParameter("@parameterName", parameter??(object)DBNull.Value)

0

मेरे पास एक ही त्रुटि संदेश था जब मैं एक संग्रहीत प्रक्रिया को कॉल करने के साथ काम कर रहा था जो दो इनपुट मापदंडों को लेता है और 3 कथन का उपयोग करके रिटर्न देता है और मैंने EF कोड प्रथम दृष्टिकोण में नीचे दिए गए मुद्दे को हल किया।

 SqlParameter @TableName = new SqlParameter()
        {
            ParameterName = "@TableName",
            DbType = DbType.String,
            Value = "Trans"
        };

SqlParameter @FieldName = new SqlParameter()
        {
            ParameterName = "@FieldName",
            DbType = DbType.String,
            Value = "HLTransNbr"
        };


object[] parameters = new object[] { @TableName, @FieldName };

List<Sample> x = this.Database.SqlQuery<Sample>("EXEC usp_NextNumberBOGetMulti @TableName, @FieldName", parameters).ToList();


public class Sample
{
    public string TableName { get; set; }
    public string FieldName { get; set; }
    public int NextNum { get; set; }
}

अद्यतन : ऐसा लगता है कि SQL सर्वर 2005 लापता EXEC कीवर्ड समस्या पैदा कर रहा है। इसलिए इसे सभी एसक्यूएल सर्वर संस्करणों के साथ काम करने की अनुमति देने के लिए मैंने अपना उत्तर अपडेट किया और नीचे की पंक्ति में EXEC को जोड़ा

 List<Sample> x = this.Database.SqlQuery<Sample>(" EXEC usp_NextNumberBOGetMulti @TableName, @FieldName", param).ToList();

कृपया नीचे लिंक देखें। कार्यकारी उपयोग करने के लिए कोई जरूरत नहीं है msdn.microsoft.com/en-us/data/jj592907.aspx
Ziggler

0

मैंने EF के साथ इस तरह से 6.x किया:

using(var db = new ProFormDbContext())
            {
                var Action = 1; 
                var xNTID = "A239333";

                var userPlan = db.Database.SqlQuery<UserPlan>(
                "AD.usp_UserPlanInfo @Action, @NTID", //, @HPID",
                new SqlParameter("Action", Action),
                new SqlParameter("NTID", xNTID)).ToList();


            }

Sqlparameter पर दोहराव न करें, कुछ लोग अपने वैरिएबल को ऐसा करते हुए जल जाते हैं

var Action = new SqlParameter("@Action", 1);  // Don't do this, as it is set below already.
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.