DbContext.Database.ExecuteSqlCommand পদ্ধতিতে কীভাবে পরামিতিগুলি পাস করবেন?


222

আসুন শুধু ধরা যাক সত্তা ফ্রেমওয়ার্কে আমার সরাসরি স্কিল কমান্ড কার্যকর করার জন্য একটি বৈধ প্রয়োজন আছে need আমার এসকিএল স্টেটমেন্টে প্যারামিটারগুলি কীভাবে ব্যবহার করতে হয় তা নির্ধারণ করতে আমার সমস্যা হচ্ছে। নিম্নলিখিত উদাহরণটি (আমার আসল উদাহরণ নয়) কাজ করে না।

var firstName = "John";
var id = 12;
var sql = @"Update [User] SET FirstName = @FirstName WHERE Id = @Id";
ctx.Database.ExecuteSqlCommand(sql, firstName, id);

এক্সিকিউটসকিউএলকম্যান্ড পদ্ধতি আপনাকে ADO.Net এর মতো নামযুক্ত প্যারামিটারগুলিতে পাস করার অনুমতি দেয় না এবং এই পদ্ধতির জন্য ডকুমেন্টেশন কীভাবে প্যারামিটারাইজড কোয়েরি কার্যকর করতে হবে তার কোনও উদাহরণ দেয় না।

আমি কীভাবে সঠিকভাবে পরামিতিগুলি নির্দিষ্ট করব?

উত্তর:


294

এটা চেষ্টা কর:

var sql = @"Update [User] SET FirstName = @FirstName WHERE Id = @Id";

ctx.Database.ExecuteSqlCommand(
    sql,
    new SqlParameter("@FirstName", firstname),
    new SqlParameter("@Id", id));

2
এটি সত্যই উত্তরটি সঠিক হিসাবে চিহ্নিত হওয়া উচিত, উপরের একটিটি আক্রমণে ঝুঁকিপূর্ণ এবং সেরা অভ্যাস নয়।
সর্বনিম্ন

8
@ মিন, গৃহীত উত্তরটি এই উত্তর ছাড়া আর আক্রমণ করার ঝুঁকিপূর্ণ নয়। সম্ভবত আপনি ভেবেছিলেন এটি স্ট্রিং ব্যবহার করছে was ফর্ম্যাট - এটি নয়।
সাইমন MᶜKenzie

1
এটি উত্তর হিসাবে চিহ্নিত করা উচিত! এটি এক এবং একমাত্র সঠিক উত্তর কারণ এটি ডেটটাইমের সাথে কাজ করে।
সোভেন

219

দেখা যাচ্ছে যে এটি কাজ করে।

var firstName = "John";
var id = 12;
var sql = "Update [User] SET FirstName = {0} WHERE Id = {1}";
ctx.Database.ExecuteSqlCommand(sql, firstName, id);

12
এটি কাজ করবে, তবে এই প্রক্রিয়াটি এসকিউএল ইঞ্জেকশনের জন্য অনুমতি দেয় এবং বিবৃতি আবার প্রদর্শিত হলেও বিভিন্ন মান সহ যখন ডেটাবেসকে একটি এক্সিকিউশন প্ল্যান পুনরায় ব্যবহার করতে বাধা দেয়।
গ্রেগ বাইলস

95
@ গ্রেগবি আমি মনে করি না আপনি এখানে ঠিক আছেন। আমি পরীক্ষা করেছি যে এটি আমাকে উদাহরণস্বরূপ কোনও স্ট্রিং শুরুর দিকে শেষ করতে দেয় না। অধিকন্তু, আমি উত্স কোডটি দেখেছি এবং দেখতে পেয়েছি যে এটি কোনও কাঁচা মানগুলিকে পরামিতিগুলিতে গুটিয়ে রাখতে DbCommand.CreateParameter ব্যবহার করছে। সুতরাং কোনও এসকিউএল ইনজেকশন নেই, এবং একটি দুর্দান্ত সুসিনেক্ট পদ্ধতিতে প্রার্থনা।
জোশ গালাগের

7
@ জোশগাল্লাগার হ্যাঁ, আপনি ঠিক বলেছেন। আমি একটি স্ট্রিংয়ের কথা ভাবছিলাম For ফর্ম্যাট দৃশ্যাবলী এটি একসাথে রাখছে।
গ্রেগ বাইলস

6
এটি এসকিউএল সার্ভার ২০০৮ আর 2 হিসাবে কাজ করে না। আপনি পাস করেছেন এমন প্যারামিটারগুলির পরিবর্তে আপনার কাছে @ p0, @ p2, ..., @pN থাকবে। SqlParameter("@paramName", value)পরিবর্তে ব্যবহার করুন।
আর্থার

ডেটাবেস টেবিল কলামগুলি এএনএসআই বারচার হিসাবে নির্দিষ্ট করা থাকলে কেউ এই ক্যোয়ারির পারফরম্যান্স প্রভাবের কথা উল্লেখ করেনি তা বিশ্বাস করা যায় না। .NET স্ট্রিংগুলি ইউনিকোড মানে প্যারামিতিগুলি সার্ভারে nvachar হিসাবে পাস করা হবে। এটি ডেটার স্তরটিকে ডেটা অনুবাদ করতে হবে বলে এটি উল্লেখযোগ্য পারফরম্যান্স সমস্যার কারণ হতে পারে। আপনার স্কেলপ্যারামিটারের সাথে যোগাযোগ করা উচিত এবং ডেটা ধরণের নির্দিষ্ট করা উচিত specify
এ কে ডি

68

অপরপক্ষে তুমি:

1) কাঁচা আর্গুমেন্ট পাস করুন এবং {0} সিনট্যাক্স ব্যবহার করুন। উদাহরণ:

DbContext.Database.SqlQuery("StoredProcedureName {0}", paramName);

2) ডিবিপ্যারামিটার সাবক্লাস আর্গুমেন্টগুলি পাস করুন এবং @ParaName সিনট্যাক্স ব্যবহার করুন।

DbContext.Database.SqlQuery("StoredProcedureName @ParamName", 
                                   new SqlParameter("@ParamName", paramValue);

আপনি যদি প্রথম সিনট্যাক্স ব্যবহার করেন, EF আসলে আপনার আর্গুমেন্টগুলি DbParamater ক্লাসের সাথে আবদ্ধ করবে, তাদের নাম নির্ধারণ করবে এবং উত্পন্ন পরামিতি নামের সাথে {0 replace প্রতিস্থাপন করবে।

প্রথম সিনট্যাক্সটি যদি পছন্দ হয় তবে কারণ আপনার কোনও কারখানা ব্যবহার করার প্রয়োজন নেই বা কী ধরণের DbParamaters তৈরি করতে হবে তা জানেন না (স্কুয়েলপ্যারামিটার, ওরাকলাপারমিটার ইত্যাদি)।


6
Mentioning 0} সিনট্যাক্সটি ডাটাবেস অজিনোস্টিক বলে উল্লেখ করার জন্য আপত্তিযুক্ত। "... আপনার কোনও কারখানা ব্যবহার করার দরকার নেই বা কী ধরণের ডিবিপাটারগুলি তৈরি করতে হবে [সিক] জানেন ..."
মাকোটোসান

পরিস্থিতি 1 একটি অন্তরবিচ্ছিন্ন সংস্করণের পক্ষে অবমুক্ত করা হয়। সমতুল্য হ'ল: ডিবিকন্টেক্সট.ড্যাটাবেস.এক্সেকিউটসকিএলআইন্টার্পোলটেড (St "স্টোরডপ্রসেসারনাম {প্যারামনেম}");
স্কটবি

20

অন্য উত্তরগুলি ওরাকল ব্যবহার করার সময় কার্যকর হয় না। :পরিবর্তে আপনার ব্যবহার করা উচিত @

var sql = "Update [User] SET FirstName = :FirstName WHERE Id = :Id";

context.Database.ExecuteSqlCommand(
   sql,
   new OracleParameter(":FirstName", firstName), 
   new OracleParameter(":Id", id));

Godশ্বরকে ধন্যবাদ যে কেউ ওরাকল ব্যবহার করে না। ভাল না স্বেচ্ছায়! সম্পাদনা: দেরিতে কৌতুকের জন্য দুঃখিত! সম্পাদনা: খারাপ রসিকতার জন্য দুঃখিত!
ক্রিস বোর্দম্যান

18

এটি চেষ্টা করুন (সম্পাদিত):

ctx.Database.ExecuteSqlCommand(sql, new SqlParameter("FirstName", firstName), 
                                    new SqlParameter("Id", id));

আগের ধারণাটি ভুল ছিল।


যখন আমি এটি করি তখন আমি নিম্নলিখিত ত্রুটিটি পাই: "অবজেক্ট টাইপ সিস্টেম থেকে কোনও ম্যাপিং উপস্থিত নেই ata ডেটা.অবজেক্টস bঅবজেক্টপ্যারামিটার একটি পরিচিত পরিচালিত সরবরাহকারী নেটিভ টাইপের জন্য" "
jessegavin

দুঃখিত আমার ভুল. ডিবিপ্যারামিটার ব্যবহার করুন।
লাডিস্লাভ Mrnka

7
DbParameter বিমূর্ত। আপনাকে একটি এসকেএলপ্যারামিটার ব্যবহার করতে হবে বা একটি ডিবিপ্যারামিটার তৈরি করতে একটি ডিবিফ্যাক্টরি ব্যবহার করতে হবে।
15-15 এ জুলম

12

সত্তা ফ্রেমওয়ার্ক কোর 2.0 বা তদুর্ধের জন্য, এটি করার সঠিক উপায় হ'ল:

var firstName = "John";
var id = 12;
ctx.Database.ExecuteSqlCommand($"Update [User] SET FirstName = {firstName} WHERE Id = {id}";

নোট করুন যে সত্তা ফ্রেমওয়ার্ক আপনার জন্য দুটি পরামিতি তৈরি করবে, সুতরাং আপনি এসকিএল ইঞ্জেকশন থেকে সুরক্ষিত।

এটিও নোট করুন:

var firstName = "John";
var id = 12;
var sql = $"Update [User] SET FirstName = {firstName} WHERE Id = {id}";
ctx.Database.ExecuteSqlCommand(sql);

কারণ এটি আপনাকে এসকিএল ইঞ্জেকশন থেকে সুরক্ষা দেয় না এবং কোনও পরামিতি তৈরি করা হয় না।

দেখুন এই আরো অনেক কিছুর জন্য।


3
আমি .NET কোর 2.0 তে খুব পছন্দ করি তা আমাকে আনন্দের অশ্রু দেয়: ')
জোশুয়া কেমারেরার

আমি কিছু লোকের উত্সাহ দেখতে পাচ্ছি। নেট কোর ২.০ এখনও পর্যন্ত আমার জন্য একটি মসৃণ যাত্রায় পরিণত হয়েছে।
পল কার্লটন

প্রথমটি কীভাবে এসকিউএল ইঞ্জেকশনের জন্য ঝুঁকিপূর্ণ নয়? উভয়ই সি # স্ট্রিং ইন্টারপোলেশন ব্যবহার করে। প্রথমটি স্ট্রিং সম্প্রসারণকে অগ্রাহ্য করতে সক্ষম হবে না, যতদূর আমি জানি। আমি সন্দেহ করেছি যে আপনি ctx.Database.ExecuteSqlCommand("Update [User] SET FirstName = {firstName} WHERE Id = {id}", firstName, id);
এটির

@ কোডনেকেড, না, আমি এটি বোঝাতে চাইনি। EF সমস্যাটি সম্পর্কে অবগত এবং আপনাকে রক্ষা করতে দুটি প্রকৃত প্যারামিটার তৈরি করে। সুতরাং এটি কেবল একটি স্ট্রিং নয় যা পেরিয়ে গেছে। বিস্তারিত জানার জন্য উপরের লিঙ্কটি দেখুন। আপনি যদি ভিএস এ চেষ্টা করে থাকেন তবে আমার সংস্করণটি এসকিএল ইঞ্জেকশন সম্পর্কে একটি সতর্কতা জারি করবে না, এবং অন্যটি তা করবে।
গ্রেগ গাম

1
@GregGum - প্রায় তিল FormattableString। আপনি ঠিক বলেছেন এবং এটি দুর্দান্ত!
কোডনেকেড

4

ওরাকলের জন্য সরলীকৃত সংস্করণ। আপনি যদি ওরাকলপ্যারামিটার তৈরি করতে না চান

var sql = "Update [User] SET FirstName = :p0 WHERE Id = :p1";
context.Database.ExecuteSqlCommand(sql, firstName, id);

2
এসকিউএল সার্ভারে আমি @ p0 এর পরিবর্তে: p0 ব্যবহার করি।
মারেক ম্যালকিজেউস্কি

3
var firstName = "John";
var id = 12;

ctx.Database.ExecuteSqlCommand(@"Update [User] SET FirstName = {0} WHERE Id = {1}"
, new object[]{ firstName, id });

এটি এত সহজ !!!

পরামিতি রেফারেন্স জানার জন্য চিত্র

এখানে চিত্র বর্ণনা লিখুন


2

অ্যাসিঙ্ক পদ্ধতির জন্য ("এক্সিকিউটসকিউএলকম্যান্ডঅ্যাসেন্স") আপনি এটি ব্যবহার করতে পারেন:

var sql = @"Update [User] SET FirstName = @FirstName WHERE Id = @Id";

await ctx.Database.ExecuteSqlCommandAsync(
    sql,
    parameters: new[]{
        new SqlParameter("@FirstName", firstname),
        new SqlParameter("@Id", id)
    });

এটি ডিবি-অজোনস্টিক নয়, এটি কেবলমাত্র এমএস-এসকিউএল সার্ভারের জন্য কাজ করবে। এটি ওরাকল বা পিজির জন্য ব্যর্থ হবে।
এনিভেস

1

যদি আপনার অন্তর্নিহিত ডাটাবেস ডেটা টাইপগুলি বার্চার হয় তবে আপনার নীচের পদ্ধতির সাথে থাকা উচিত। অন্যথায় ক্যোয়ারিতে একটি বিশাল কর্মক্ষমতা প্রভাব ফেলবে।

var firstName = new SqlParameter("@firstName", System.Data.SqlDbType.VarChar, 20)
                            {
                                Value = "whatever"
                            };

var id = new SqlParameter("@id", System.Data.SqlDbType.Int)
                            {
                                Value = 1
                            };
ctx.Database.ExecuteSqlCommand(@"Update [User] SET FirstName = @firstName WHERE Id = @id"
                               , firstName, id);

পার্থক্যটি দেখতে আপনি এসকিএল প্রোফাইলার চেক করতে পারেন।


0
public static class DbEx {
    public static IEnumerable<T> SqlQueryPrm<T>(this System.Data.Entity.Database database, string sql, object parameters) {
        using (var tmp_cmd = database.Connection.CreateCommand()) {
            var dict = ToDictionary(parameters);
            int i = 0;
            var arr = new object[dict.Count];
            foreach (var one_kvp in dict) {
                var param = tmp_cmd.CreateParameter();
                param.ParameterName = one_kvp.Key;
                if (one_kvp.Value == null) {
                    param.Value = DBNull.Value;
                } else {
                    param.Value = one_kvp.Value;
                }
                arr[i] = param;
                i++;
            }
            return database.SqlQuery<T>(sql, arr);
        }
    }
    private static IDictionary<string, object> ToDictionary(object data) {
        var attr = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance;
        var dict = new Dictionary<string, object>();
        foreach (var property in data.GetType().GetProperties(attr)) {
            if (property.CanRead) {
                dict.Add(property.Name, property.GetValue(data, null));
            }
        }
        return dict;
    }
}

ব্যবহার:

var names = db.Database.SqlQueryPrm<string>("select name from position_category where id_key=@id_key", new { id_key = "mgr" }).ToList();

7
যে কোনও সুযোগ আপনি এই কোডটি ব্যাখ্যা করতে পারলেন এবং কেন এটি উত্থাপিত প্রশ্নের উত্তর, যাতে যারা পরে এসে এটি খুঁজে পায় তারা এটি বুঝতে পারে?
অ্যান্ড্রু বারবার

1
Read 0} সিনট্যাক্স নিয়ে সমস্যা যা আপনি পঠনযোগ্যতা শিথিল করেছেন - আমি ব্যক্তিগতভাবে এটি পছন্দ করি না। আপনাকে DbParameter (SQLlParameter, OracleParameter ইত্যাদির) এর কংক্রিট বাস্তবায়ন নির্দিষ্ট করতে হবে এমন স্কেলপ্যারামিটারগুলি পাস করার ক্ষেত্রে সমস্যা। প্রদত্ত উদাহরণ আপনাকে এই সমস্যাগুলি এড়াতে দেয়।
Neco

3
আমি অনুমান করি যে এটি একটি বৈধ মতামত, তবে আপনি আসলে এখানে জিজ্ঞাসা করা প্রশ্নের উত্তর দেননি; কীভাবে প্যারামিটারগুলি পাস ExecuteSqlCommand()করবেন আপনার উত্তর পোস্ট করার সময় আপনার নির্দিষ্ট প্রশ্ন জিজ্ঞাসা করা উচিত তা নিশ্চিত হওয়া উচিত।
অ্যান্ড্রু বারবার

3
ডাউনভোটেড কারণ এটি অকারণে জটিল (যেমন প্রতিবিম্ব ব্যবহার করে, চাকাটি পুনরায় উদ্ভাবন করে, বিভিন্ন ডাটাবেস সরবরাহকারীদের জন্য অ্যাকাউন্টে ব্যর্থ হয়)
একটি ফু

আপ-ভোট দেওয়া হয়েছে কারণ এটি সম্ভাব্য সমাধানগুলির মধ্যে একটি দেখায়। আমি নিশ্চিত যে এক্সিকিউট এসকিএলকম্যান্ড স্কেলকিউরি একইভাবে প্যারামিটার গ্রহণ করে I প্যারামিটারগুলি পাস করার Dapper.net স্টাইলটিও আমি পছন্দ করি।
জার শারদান

0

সঞ্চিত পদ্ধতিতে একাধিক প্যারাম যার ভিবিতে একাধিক প্যারাম রয়েছে:

Dim result= db.Database.ExecuteSqlCommand("StoredProcedureName @a,@b,@c,@d,@e", a, b, c, d, e)

0

সঞ্চিত পদ্ধতিগুলি নীচের মতো কার্যকর করা যায়

 string cmd = Constants.StoredProcs.usp_AddRoles.ToString() + " @userId, @roleIdList";
                        int result = db.Database
                                       .ExecuteSqlCommand
                                       (
                                          cmd,
                                           new SqlParameter("@userId", userId),
                                           new SqlParameter("@roleIdList", roleId)
                                       );


0

.NET কোর 2.2 এর জন্য, আপনি FormattableStringগতিশীল এসকিউএল ব্যবহার করতে পারেন ।

//Assuming this is your dynamic value and this not coming from user input
var tableName = "LogTable"; 
// let's say target date is coming from user input
var targetDate = DateTime.Now.Date.AddDays(-30);
var param = new SqlParameter("@targetDate", targetDate);  
var sql = string.Format("Delete From {0} Where CreatedDate < @targetDate", tableName);
var froamttedSql = FormattableStringFactory.Create(sql, param);
_db.Database.ExecuteSqlCommand(froamttedSql);

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.