সত্তা ফ্রেমওয়ার্কে আমি কীভাবে একাধিক সারি মুছব (পূর্বে বিনা)


305

সত্তা ফ্রেমওয়ার্ক ব্যবহার করে আমি টেবিল থেকে বেশ কয়েকটি আইটেম মুছে ফেলছি। কোনও বিদেশী কী / প্যারেন্ট অবজেক্ট নেই তাই আমি এটি অনডিলিটক্যাসকেড দিয়ে পরিচালনা করতে পারি না।

এখনই আমি এটি করছি:

var widgets = context.Widgets
    .Where(w => w.WidgetId == widgetId);

foreach (Widget widget in widgets)
{
    context.Widgets.DeleteObject(widget);
}
context.SaveChanges();

এটি কাজ করে তবে ফোরচ আমাকে বাগ দেয় gs আমি EF4 ব্যবহার করছি তবে আমি এসকিউএল কার্যকর করতে চাই না। আমি শুধু নিশ্চিত করতে চাই যে আমি কিছুই মিস করছি না - এটি যতটা পেয়েছে ঠিক ততই ঠিক তাই না? আমি এটি কোনও এক্সটেনশান পদ্ধতি বা সাহায্যকারীর সাথে বিমূর্ত করতে পারি, তবে কোথাও আমরা এখনও একটি ভবিষ্যদ্বাণী করব, তাই না?


1
আপনি গৃহীত উত্তরটি আবার দেখতে চান।
এরিক জে

1
আপনি যদি পারফরম্যান্ট থাকতে চান তবে আপনি আমার উত্তরটি এখানে দেখতে চান স্ট্যাকওভারফ্লো.com
আদি

উত্তর:


49

আপনি যদি এসকিউএল চালাতে না চান তবে সরাসরি একটি লুপে ডিলিটঅবজেক্টকে কল করা আপনি আজ করতে পারেন সেরা।

তবে আপনি এসকিউএল কার্যকর করতে পারেন এবং এখনও আমি এখানে বর্ণিত পদ্ধতির ব্যবহার করে এটি একটি এক্সটেনশন পদ্ধতির মাধ্যমে সম্পূর্ণ সাধারণ উদ্দেশ্যে তৈরি করতে পারি ।

যদিও সেই উত্তরটি ছিল ৩.৫ এর জন্য। 4.0 এর জন্য আমি সম্ভবত স্টোর সংযোগে নেমে না গিয়ে হুডের নীচে নতুন এক্সিকিউটস্টোরকম্যান্ড এপিআই ব্যবহার করব।


এক্সিকিউটস্টোরকম্যান্ডটি কোনও সঠিক উপায় নয় lete ডিলিটএলসবমিট লিনাক টু এসকিএল-তে কাজ করছেন তবে সত্তা কাঠামোর ক্ষেত্রে নয়। সত্তা কাঠামোতে আমি একই বিকল্প চাই।
হিরাল

653

এন্টিফ্রেমওয়ার্ক 6 এর মাধ্যমে এটি কিছুটা সহজ করেছে .RemoveRange()

উদাহরণ:

db.People.RemoveRange(db.People.Where(x => x.State == "CA"));
db.SaveChanges();

31
আমাদের যা প্রয়োজন তা হ'ল ... আমি যখন এটি পর্যাপ্ত পরিমাণে ব্যবহার করি তবে আমি স্মৃতি ছাড়াই ব্যতিক্রম পাই! আমি ভেবেছিলাম সরানরেঞ্জের পুরো বিন্দুটি প্রক্রিয়াকরণটি ডাটাবেসে পাস করা ছিল, তবে দৃশ্যত নয়।
সমর আদ্রা

মুছে ফেলা রাষ্ট্রকে প্রতিটি সত্তায় সেট করার চেয়ে এটি WAAAYYYY দ্রুত!
জেরেটার

54
নিশ্চিতরূপে এই উত্তরটি সহজ তবে কর্মক্ষমতা অনুযায়ী এটি দুর্দান্ত নাও হতে পারে। কেন? এই বহিরাগত দোয়াতটি ফোরচ লুপে এটি মুছে ফেলার সমান, এটি প্রথমে সমস্ত সারি নিয়ে আসে এবং তারপরে মুছে ফেলা একে একে হয়, কেবল লাভ সংরক্ষণের জন্য হয় "ডিটেকট চেঞ্জগুলি কোনও সত্তা মোছার আগে একবার কল করা হবে এবং" পুনরায় "বলা হবে না একই, এসকিউএল উত্পন্ন করার জন্য সরঞ্জামটি ব্যবহার করে দেখুন।
আনশুল নিগম

6
বড় পর্যাপ্ত পরিসরের জন্য, রিট্র্যাং (...) অবধি গণনা করুন (10000) এবং লুপিং এর মতো কিছু চেষ্টা করুন Count গণনা () == ০.
এরিক জে।

20
সমস্যাটি হ'ল সরানরেঞ্জ ইনপুট প্যারামিটারটি একটি আইওনিউরেবল তাই এটি মুছে ফেলার জন্য এটি সমস্ত সত্ত্বাকে গণ্য করে এবং প্রতি সত্তা 1 ডিলেট ডিফল্ট ক্যোয়ারি চালায়।
বুবি

74

এটি যেমন এটি পায় ঠিক তাই না? আমি এটি কোনও এক্সটেনশান পদ্ধতি বা সাহায্যকারীর সাথে বিমূর্ত করতে পারি, তবে কোথাও আমরা এখনও একটি ভবিষ্যদ্বাণী করব, তাই না?

ঠিক আছে, হ্যাঁ, আপনি এটিকে দ্বি-লাইন তৈরি করতে পারবেন না:

context.Widgets.Where(w => w.WidgetId == widgetId)
               .ToList().ForEach(context.Widgets.DeleteObject);
context.SaveChanges();

76
আপনি একটি টোললিস্ট () করছেন যা উদ্দেশ্যকে পরাস্ত করে। মূল সমাধান থেকে এটি কীভাবে আলাদা?
lahsrah

3
আমার কাছে সমস্যা আছে যেহেতু আমার কেবল প্রসঙ্গ অবজেক্টে সরান পদ্ধতি রয়েছে।
Pnct

2
মিলিয়ন সারি (অথবা কয়েকশত) এমনকি প্রত্যাশিত হলে এটি অবশ্যই উপযুক্ত সমাধান নয়। তবে আমরা যদি নিশ্চিতভাবে জানতে পারি যে কয়েকটি সারি থাকবে তবে এই সমাধানটি পরিষ্কার এবং পুরোপুরি ভালভাবে কাজ করে। হ্যাঁ, এটি ডিবিতে কয়েকটি রাউন্ড ট্রিপ জড়িত করতে পারে, তবে আমার মতে এসকিউএলকে সরাসরি কল করার সাথে জড়িত হারানো বিমূর্তি সুবিধার চেয়ে বেশি।
যোগস্টার

নাম অনুসারে সত্তা ফ্রেমওয়ার্ক সত্তা স্তরের ডেটা সহ সেরা কাজ করে। বেশিরভাগ ডেটা ক্রিয়াকলাপগুলি ভাল পুরানো সঞ্চিত প্রোকগুলি দ্বারা পরিচালনা করা হয়। পারফরম্যান্স-ভিত্তিতে তারা এখন পর্যন্ত সর্বোত্তম বিকল্প এবং লুপের জন্য প্রয়োজনীয় কোনও EF যুক্তিকে পরাজিত করবে।
পেসম্যান

72
using (var context = new DatabaseEntities())
{
    context.ExecuteStoreCommand("DELETE FROM YOURTABLE WHERE CustomerID = {0}", customerId);
}

তবে আপনি কীভাবে আইডির তালিকা দিয়ে এটি করতে পারেন? এই সমাধানটি খুব ভাল "তালিকাগুলি" পরিচালনা করে না।
জেসি নিউম্যান

11
@ জেসি নিউম্যান 19 আপনার যদি ইতিমধ্যে আইডির তালিকা থাকে তবে একটি ব্যবহার করুন WHERE IN ({0})এবং তারপরে দ্বিতীয় যুক্তিটি হওয়া উচিত String.Join(",", idList)
ল্যাংডন

@ ল্যাংডন যা কাজ করবে না, কারণ এটি কমান্ডটি এর মতো স্কয়ারে প্রেরণ করবে: যেখানে ("1, 2, 3")। ডাটাবেসটি তখন একটি ত্রুটি ছুড়ে দেয় কারণ আপনি এটি পূর্ণসংখ্যার তালিকার পরিবর্তে একটি স্ট্রিং পাস করেছেন।
জেসি নিউম্যান 19

আমি লিনকিউ-এর সাথে একটি বিবৃতি উত্পন্ন করতে চাই। আমি যে নিকটতম জিনিসটি পেয়েছি তা ছিল একটি শৃঙ্খলা। EntityFramework.Extended
জয়দার

আপনি যদি ব্যবহার করে থাকেন তবে আপনার ইতিমধ্যে গঠিত এসকিউএল স্ট্রিংটি কমান্ডটিতে String.Joinব্যবহার string.Formatএবং পাস করার প্রয়োজন হতে পারে । যতক্ষণ না আপনার তালিকার কেবল পূর্ণসংখ্যা রয়েছে ততক্ষণ ইনজেকশন আক্রমণের ঝুঁকি নেই। এই প্রশ্নটি দেখুন: আমি কীভাবে একটি এক্সিকিউট স্টোর কমান্ডের একটি অ্যারে পাস করতে পারি?
অ্যান্ড্রু

50

আমি জানি এটি বেশ দেরি হয়ে গেছে তবে কারও কাছে যদি সহজ সমাধানের প্রয়োজন হয় তবে দুর্দান্ত জিনিসটি আপনি এটির সাথে এখানে ক্লজটি যুক্ত করতে পারেন:

public static void DeleteWhere<T>(this DbContext db, Expression<Func<T, bool>> filter) where T : class
{
    string selectSql = db.Set<T>().Where(filter).ToString();
    string fromWhere = selectSql.Substring(selectSql.IndexOf("FROM"));
    string deleteSql = "DELETE [Extent1] " + fromWhere;
    db.Database.ExecuteSqlCommand(deleteSql);
}

দ্রষ্টব্য: সবেমাত্র এমএসএসকিউএল ২০০8 দিয়ে পরীক্ষা করা হয়েছে।

হালনাগাদ:

EF পরামিতিগুলির সাথে বর্গ স্টেটমেন্ট উত্পন্ন করার সময় উপরের সমাধানটি কাজ করবে না , সুতরাং EF5 এর আপডেট এখানে দেওয়া হয়েছে :

public static void DeleteWhere<T>(this DbContext db, Expression<Func<T, bool>> filter) where T : class
{
    var query = db.Set<T>().Where(filter);

    string selectSql = query.ToString();
    string deleteSql = "DELETE [Extent1] " + selectSql.Substring(selectSql.IndexOf("FROM"));

    var internalQuery = query.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Where(field => field.Name == "_internalQuery").Select(field => field.GetValue(query)).First();
    var objectQuery = internalQuery.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Where(field => field.Name == "_objectQuery").Select(field => field.GetValue(internalQuery)).First() as ObjectQuery;
    var parameters = objectQuery.Parameters.Select(p => new SqlParameter(p.Name, p.Value)).ToArray();

    db.Database.ExecuteSqlCommand(deleteSql, parameters);
}

এতে কিছুটা প্রতিবিম্ব প্রয়োজন তবে এটি ভালভাবে কাজ করে।


ডিবি কনটেক্সট কী? আমি আপনার স্বতঃ-উত্পন্ন সত্তা কাঠামো প্রসঙ্গে ধরে নিই? আমার কাছে <<> সেট নামক কোনও পদ্ধতি নেই।
স্টিলথ রাব্বি

@ স্টিলথ: হ্যাঁ, এটি আপনার EF ডেটা প্রসঙ্গে, আমি কোড-ফার্স্ট ব্যবহার করি তবে স্বয়ংক্রিয়ভাবে উত্পন্ন উত্সটি একই হওয়া উচিত। ভুল টাইপযুক্ত বক্তব্যের জন্য দুঃখিত এটি সেট করা উচিত <টি> () (আমার সংস্থা ইন্টারনেট অ্যাক্সেসকে নিয়ন্ত্রণ করে যে আমি কোডটি আটকাতে পারিনি, হাতে টাইপ করতে হয়েছিল ...), কোডগুলি আপডেট করা হয়েছে :)
থানহ এনগুইন

3
এই একমাত্র উত্তর যা আসলে প্রশ্নের উত্তর দেয়! প্রতিটি অন্যান্য উত্তর একক সময়ে প্রতিটি স্বতন্ত্র আইটেম মুছে ফেলে, অবিশ্বাস্য।
রক্লান

এটি সবচেয়ে সঠিক উত্তর বলে মনে হচ্ছে। এটি খুব সাধারণ উপায়ে মোছার অনুমতি দেয় এবং এটি সি # নয়, ডাটাবেসটিতে সঠিকভাবে কাজটি অফলোড করে।
জেসি নিউম্যান

1
সমস্ত কম প্রযুক্তিগত প্রোগ্রামারদের জন্য, আমি কীভাবে এই দুর্দান্ত এবং জেনেরিক সমাধানটি বাস্তবায়িত করতে পারি সে সম্পর্কে আরও কিছুটা ব্যাখ্যা করতে চেয়েছিলাম, কারণ এটি আমার কয়েক মিনিটের সময় বাঁচাতে পারত! পরবর্তী মন্তব্যে অবিরত ...
jdnew18

30

যে কেউ EF5 ব্যবহার করে, নিম্নলিখিত এক্সটেনশন লাইব্রেরিটি ব্যবহার করা যেতে পারে: https://github.com/loresoft/EntityFramework.Extended

context.Widgets.Delete(w => w.WidgetId == widgetId);

3
বড় টেবিলগুলিতে পারফরম্যান্স সম্পর্কিত সমস্যা রয়েছে, আমার অবস্থাতে ব্যবহারযোগ্য নয়।
টমাস

@ টমাস কি ধরণের পারফরম্যান্স জারি করেছেন? বিষয়টি কতটা তীব্র ছিল এবং টেবিলটি কতটা বড় ছিল? অন্য কেউ তা নিশ্চিত করতে পারবেন?
অ্যানেস্টিস কিভরনগ্লোউ

সেখানকার বিকল্পগুলির সাথে এটি খুব দ্রুত তুলনা করা যায়
জয়দার

আমি Delete()EF6 এ আমার সত্ত্বায় ফাংশন দেখতে পাচ্ছি না ।
ডটনেট

context.Widgets.Where(w => w.WidgetId == widgetId).Delete();সত্তা ফ্রেমওয়ার্কের সাথে এক নতুন উপায় E প্রসারিত
পিটার কের

11

এখনও এটি মুছে ফেলার জন্য সার্ভার থেকে কিছু পিছনে ফিরে আসতে পাগল বলে মনে হচ্ছে, তবে কমপক্ষে আইডিগুলি ফিরিয়ে নেওয়া সম্পূর্ণ সত্ত্বাগুলি নীচে টানানোর চেয়ে অনেক ঝুঁকিপূর্ণ:

var ids = from w in context.Widgets where w.WidgetId == widgetId select w.Id;
context.Widgets.RemoveRange(from id in ids.AsEnumerable() select new Widget { Id = id });

সতর্কতা অবলম্বন করুন - এটি সত্ত্বা ফ্রেমওয়ার্কের সত্তার বৈধতা ব্যর্থ করতে পারে কারণ আপনার স্টাব Widgetঅবজেক্টের কেবল একটি প্রাথমিক Idসম্পত্তি রয়েছে। এর চারপাশের context.Configuration.ValidateOnSaveEnabled = falseউপায়টি হ'ল (কমপক্ষে EF6 এ)। এটি সত্ত্বা ফ্রেমওয়ার্কের নিজস্ব বৈধতা অক্ষম করে, তবে এখনও ডাটাবেসের নিজস্ব বৈধতা অবশ্যই সম্পাদন করে।
স্যামি এস।

@SammyS। আমি এটি অভিজ্ঞতা অর্জন করি নি, সুতরাং বিশদগুলির সাথে কথা বলতে পারব না, তবে এটি বিজোড় বলে মনে হচ্ছে যে কোনওভাবে সারিটি মোছার সময় EF বৈধতার সাথে বিরক্ত করবে।
এডওয়ার্ড ব্রে

আপনি একেবারে সঠিক। সত্তাগুলি লোড না করে deleteআইএনএস দেওয়ার জন্য একই ধরণের কাজের সাথে আমি বিভ্রান্ত হয়েছি update
স্যামি এস।

10

EF 6.1

public void DeleteWhere<TEntity>(Expression<Func<TEntity, bool>> predicate = null) 
where TEntity : class
{
    var dbSet = context.Set<TEntity>();
    if (predicate != null)
        dbSet.RemoveRange(dbSet.Where(predicate));
    else
        dbSet.RemoveRange(dbSet);

    context.SaveChanges();
} 

ব্যবহার:

// Delete where condition is met.
DeleteWhere<MyEntity>(d => d.Name == "Something");

Or:

// delete all from entity
DeleteWhere<MyEntity>();

7
এটি কার্যকরভাবে db.People.RemoveRange (db.People.Where (x => x.State == "CA")) এর সমান; db.SaveChanges (); সুতরাং কোন পারফরম্যান্স লাভ।
ReinierDG

4

EF 4.1 এর জন্য,

var objectContext = (myEntities as IObjectContextAdapter).ObjectContext;
objectContext.ExecuteStoreCommand("delete from [myTable];");

1
এটি কাজ করে, তবে সত্তা ফ্রেমওয়ার্ক ব্যবহারের পুরো পয়েন্টটিতে ডাটাবেসের সাথে ইন্টারঅ্যাক্ট করার জন্য একটি অবজেক্ট ভিত্তিক উপায় রয়েছে। এটি সরাসরি এসকিউএল কোয়েরিটি চালাচ্ছে।
আর্টুরো টরেস সানচেজ

4

এটি করার জন্য আপনি এক্সটেনশন লাইব্রেরি ব্যবহার করতে পারেন যেমন এন্টিফ্রেমওয়ার্ক work এক্সটেন্ডেড বা জেড.এন্টি ফ্রেমওয়ার্ক work প্লাস.এইফ,, এখানে EF 5, 6 বা কোরের জন্য উপলব্ধ। আপনাকে মুছতে বা আপডেট করতে হবে এবং সেগুলি লিনকিউ ব্যবহার করার সময় এই লাইব্রেরিগুলির দুর্দান্ত পারফরম্যান্স রয়েছে। মুছে ফেলার উদাহরণ ( উত্স প্লাস ):

ctx.Users.Where(x => x.LastLoginDate < DateTime.Now.AddYears(-2)) .Delete();

বা ( উত্স বর্ধিত )

context.Users.Where(u => u.FirstName == "firstname") .Delete();

এগুলি নেটিভ এসকিউএল স্টেটমেন্ট ব্যবহার করে, তাই পারফরম্যান্স দুর্দান্ত।


বাল্ক স্কোয়েল অপারেশন জেনারেটরের জন্য 600। + প্রদান করুন। সিরিয়াসলি?
nicolay.anykienko

@ নিকোলে.নেইকিয়েনকো যখন আমি এটি ব্যবহার করেছি, এই গ্রন্থাগারটি বিনামূল্যে ছিল, অন্যান্য ক্রিয়াকলাপ রয়েছে যেখানে আপনাকে অর্থ প্রদান করতে হবে, ঠিক নেই আমি আপনাকে জানাতে হবে কিনা তাও জানি না
উউহিভস

3

মুছে ফেলার দ্রুততম উপায় হ'ল সঞ্চিত পদ্ধতি ব্যবহার করা। আমি গতিশীল এসকিউএল এর চেয়ে বেশি একটি ডাটাবেস প্রকল্পে সঞ্চিত পদ্ধতি পছন্দ করি কারণ নামগুলি সঠিকভাবে পরিচালনা করা হবে এবং সংকলক ত্রুটি থাকবে। গতিশীল এসকিউএল চালিত সময়ের ত্রুটির কারণে মুছে ফেলা / নাম বদলে দেওয়া টেবিলগুলি উল্লেখ করতে পারে।

এই উদাহরণে, আমার কাছে দুটি টেবিল রয়েছে তালিকা এবং তালিকা আইটেম। প্রদত্ত তালিকার সমস্ত তালিকা আইটেম মুছতে আমার দ্রুত উপায় দরকার।

CREATE TABLE [act].[Lists]
(
    [Id] INT NOT NULL PRIMARY KEY IDENTITY, 
    [Name] NVARCHAR(50) NOT NULL
)
GO
CREATE UNIQUE INDEX [IU_Name] ON [act].[Lists] ([Name])
GO
CREATE TABLE [act].[ListItems]
(
    [Id] INT NOT NULL IDENTITY, 
    [ListId] INT NOT NULL, 
    [Item] NVARCHAR(100) NOT NULL, 
    CONSTRAINT PK_ListItems_Id PRIMARY KEY NONCLUSTERED (Id),
    CONSTRAINT [FK_ListItems_Lists] FOREIGN KEY ([ListId]) REFERENCES [act].[Lists]([Id]) ON DELETE CASCADE
)
go
CREATE UNIQUE CLUSTERED INDEX IX_ListItems_Item 
ON [act].[ListItems] ([ListId], [Item]); 
GO

CREATE PROCEDURE [act].[DeleteAllItemsInList]
    @listId int
AS
    DELETE FROM act.ListItems where ListId = @listId
RETURN 0

আইটেমগুলি মুছতে এবং একটি এক্সটেনশন ব্যবহার করে সত্তা ফ্রেমওয়ার্ক আপডেট করার আকর্ষণীয় অংশ।

public static class ListExtension
{
    public static void DeleteAllListItems(this List list, ActDbContext db)
    {
        if (list.Id > 0)
        {
            var listIdParameter = new SqlParameter("ListId", list.Id);
            db.Database.ExecuteSqlCommand("[act].[DeleteAllItemsInList] @ListId", listIdParameter);
        }
        foreach (var listItem in list.ListItems.ToList())
        {
            db.Entry(listItem).State = EntityState.Detached;
        }
    }
}

মূল কোডটি এখন এটি ব্যবহার করতে পারে

[TestMethod]
public void DeleteAllItemsInListAfterSavingToDatabase()
{
    using (var db = new ActDbContext())
    {
        var listName = "TestList";
        // Clean up
        var listInDb = db.Lists.Where(r => r.Name == listName).FirstOrDefault();
        if (listInDb != null)
        {
            db.Lists.Remove(listInDb);
            db.SaveChanges();
        }

        // Test
        var list = new List() { Name = listName };
        list.ListItems.Add(new ListItem() { Item = "Item 1" });
        list.ListItems.Add(new ListItem() { Item = "Item 2" });
        db.Lists.Add(list);
        db.SaveChanges();
        listInDb = db.Lists.Find(list.Id);
        Assert.AreEqual(2, list.ListItems.Count);
        list.DeleteAllListItems(db);
        db.SaveChanges();
        listInDb = db.Lists.Find(list.Id);
        Assert.AreEqual(0, list.ListItems.Count);
    }
}

সঞ্চিত প্রক্রিয়াটি ব্যবহারের এবং উদাহরণস্বরূপ ব্যবহারের কোড সহ এটি এক্সটেনশন হিসাবে কার্যকর করার জন্য একটি দুর্দান্ত উদাহরণের জন্য আপনাকে ধন্যবাদ।
গ্লেন গারসন

3

আপনি যদি কোনও টেবিলের সমস্ত সারি মুছে ফেলতে চান তবে আপনি sql কমান্ড কার্যকর করতে পারেন

using (var context = new DataDb())
{
     context.Database.ExecuteSqlCommand("TRUNCATE TABLE [TableName]");
}

ট্র্যাঙ্কেট টেবিল (লেনদেন-এসকিউএল) পৃথক সারি মুছে ফেলা লগ না করে একটি সারণী থেকে সমস্ত সারি সরিয়ে দেয়। ট্র্যাঙ্কেট টেবিল হ'ল ডিল স্টেটমেন্টের সাথে সমান যেখানে কোনও বিধি নেই; তবে ট্র্যাঙ্কেট টেবলটি দ্রুত এবং কম সিস্টেম এবং লেনদেন লগ সংস্থান ব্যবহার করে।


3
আপনার এও উল্লেখ করা উচিত যে আপনি যে truncate tableটেবিলে বিদেশী কী বাধা দ্বারা রেফারেন্স দেওয়া যায় তা চালাতে পারবেন না । (আপনি কোনও টেবিলটি কেটে ফেলতে পারেন যার একটি বিদেশী কী রয়েছে যা উল্লেখ করে ferences)। এমএসডিএন ডকুমেন্টেশন
ব্রডব্যান্ড

2

UUHHIVSব্যাচ মোছার জন্য এটি একটি খুব মার্জিত এবং দ্রুত উপায়, তবে এটি অবশ্যই যত্ন সহ ব্যবহার করা উচিত:

  • লেনদেনের স্বতঃ উত্পাদন: এর অনুসন্ধানগুলি একটি লেনদেনের দ্বারা পরিবেষ্টিত হবে
  • ডাটাবেস প্রসঙ্গে স্বাধীনতা: এর কার্যকর করার কোনও সম্পর্ক নেই context.SaveChanges()

এই বিষয়গুলি লেনদেনের নিয়ন্ত্রণ গ্রহণের মাধ্যমে সমাধান করা যায়। নিম্নলিখিত কোডটি ব্যাচকে কীভাবে লেনদেন করতে হবে এবং একটি লেনদেনের পদ্ধতিতে বাল্ক সন্নিবেশ করা যায় তা চিত্রিত করে:

var repo = DataAccess.EntityRepository;
var existingData = repo.All.Where(x => x.ParentId == parentId);  

TransactionScope scope = null;
try
{
    // this starts the outer transaction 
    using (scope = new TransactionScope(TransactionScopeOption.Required))
    {
        // this starts and commits an inner transaction
        existingData.Delete();

        // var toInsert = ... 

        // this relies on EntityFramework.BulkInsert library
        repo.BulkInsert(toInsert);

        // any other context changes can be performed

        // this starts and commit an inner transaction
        DataAccess.SaveChanges();

        // this commit the outer transaction
        scope.Complete();
    }
}
catch (Exception exc)
{
    // this also rollbacks any pending transactions
    scope?.Dispose();
}

2

সত্তা ফ্রেমওয়ার্ক কোর

3.1 3.0 2.2 2.1 2.0 1.1 1.0

using (YourContext context = new YourContext ())
{
    var widgets = context.Widgets.Where(w => w.WidgetId == widgetId);
    context.Widgets.RemoveRange(widgets);
    context.SaveChanges();
}

সংক্ষিপ্তসার :

প্রতিটি সত্তা মুছে ফেলা অবস্থায় রেখে এমন সেটের অন্তর্নিহিত প্রসঙ্গ থেকে সত্তাগুলির প্রদত্ত সংগ্রহটিকে সরিয়ে দেয় যেমন সেভচেনজেস ডাকা হলে এটি ডাটাবেস থেকে মুছে ফেলা হবে।

মন্তব্য :

মনে রাখবেন যে যদি System.Data.Entity.Inf संरचना.DbContextConfigration.A AutoDetectChangesEnabled সত্যতে সেট করা থাকে (যা পূর্বনির্ধারিত), তারপরে কোনও সত্তা মোছার আগেই ডিটেকট চেঞ্জগুলি একবার কল করা হবে এবং আবার কল হবে না। এর অর্থ হ'ল কিছু পরিস্থিতিতে রিম্যারেঞ্জ কলকে রিমুভ করার চেয়ে একাধিকবার কল করার চেয়ে উল্লেখযোগ্যভাবে পারফরম্যান্স করতে পারে। মনে রাখবেন যে যুক্ত অবস্থায় থাকা অবস্থায় কোনও সত্তা যদি প্রসঙ্গে উপস্থিত থাকে তবে এই পদ্ধতিটি এটিকে প্রসঙ্গ থেকে বিচ্ছিন্ন করে তুলবে। এটি কারণ এই যে কোনও সংযুক্ত সত্তার ডাটাবেজে উপস্থিত থাকার কথা ধারণা করা হয় না যে এটি মুছতে চেষ্টা করার কোনও অর্থ হয় না।


1

আপনি নিম্নলিখিত হিসাবে সরাসরি বর্গ কোয়েরি কার্যকর করতে পারেন:

    private int DeleteData()
{
    using (var ctx = new MyEntities(this.ConnectionString))
    {
        if (ctx != null)
        {

            //Delete command
            return ctx.ExecuteStoreCommand("DELETE FROM ALARM WHERE AlarmID > 100");

        }
    }
    return 0;
}

নির্বাচনের জন্য আমরা ব্যবহার করতে পারি

using (var context = new MyContext()) 
{ 
    var blogs = context.MyTable.SqlQuery("SELECT * FROM dbo.MyTable").ToList(); 
}

EF সঠিকভাবে মুছে ফেলা শর্তাদি ম্যাপিং সমর্থন করে না এটি দেওয়া সম্ভবত কাজটি করার জন্য এটি আপনার সেরা বাজি bet
টনি ও'হাগান

1

আপনি নিজের ফলাফলগুলি ভেরের পরিবর্তে জেনেরিক তালিকায় পাস করে মুছে ফেলুন AllAnSubmit () পদ্ধতিটিও ব্যবহার করতে পারেন । এইভাবে আপনার ভবিষ্যদ্বাণী কোডের এক লাইনে হ্রাস পেয়েছে:

List<Widgets> widgetList = context.Widgets
              .Where(w => w.WidgetId == widgetId).ToList<Widgets>();

context.Widgets.DeleteAllOnSubmit(widgetList);

context.SubmitChanges();

এটি সম্ভবত অভ্যন্তরীণভাবে এখনও একটি লুপ ব্যবহার করে।


3
দেখে মনে হচ্ছে আপনি কী তা ভুল বোঝাচ্ছেন var
স্বাধীনতা-এম

1

থানহর উত্তর আমার পক্ষে সবচেয়ে ভাল কাজ করেছে। একক সার্ভার ট্রিপে আমার সমস্ত রেকর্ড মুছে ফেলা হয়েছে। আমি আসলে এক্সটেনশন পদ্ধতিটি কল করার সাথে লড়াই করেছি, তাই ভেবেছিলাম আমি আমার ভাগ করব (EF 6):

আমি আমার এমভিসি প্রকল্পের একটি সহায়ক শ্রেণিতে এক্সটেনশন পদ্ধতি যুক্ত করেছি এবং নামটি "সরানওহ্যারে" পরিবর্তন করেছি। আমি আমার কন্ট্রোলারগুলিতে একটি ডিবি কনটেক্সট ইনজেক্ট করি তবে আপনি এটিও করতে পারেন using

// make a list of items to delete or just use conditionals against fields
var idsToFilter = dbContext.Products
    .Where(p => p.IsExpired)
    .Select(p => p.ProductId)
    .ToList();

// build the expression
Expression<Func<Product, bool>> deleteList = 
    (a) => idsToFilter.Contains(a.ProductId);

// Run the extension method (make sure you have `using namespace` at the top)
dbContext.RemoveWhere(deleteList);

এটি গ্রুপটির জন্য একক মুছে ফেলার বিবরণ তৈরি করেছে।


0

EF 6। =>

var assignmentAddedContent = dbHazirBot.tbl_AssignmentAddedContent.Where(a =>
a.HazirBot_CategoryAssignmentID == categoryAssignment.HazirBot_CategoryAssignmentID);
dbHazirBot.tbl_AssignmentAddedContent.RemoveRange(assignmentAddedContent);
dbHazirBot.SaveChanges();

0

সেরা: in EF6 => .RemoveRange()

উদাহরণ:

db.Table.RemoveRange(db.Table.Where(x => Field == "Something"));

14
কীভাবে এটি কাইলের উত্তর থেকে আলাদা?

-1

উত্তর 'কোডের প্রিয় বিট' দেখুন যা কাজ করে

এখানে আমি এটি কীভাবে ব্যবহার করেছি:

     // Delete all rows from the WebLog table via the EF database context object
    // using a where clause that returns an IEnumerable typed list WebLog class 
    public IEnumerable<WebLog> DeleteAllWebLogEntries()
    {
        IEnumerable<WebLog> myEntities = context.WebLog.Where(e => e.WebLog_ID > 0);
        context.WebLog.RemoveRange(myEntities);
        context.SaveChanges();

        return myEntities;
    }

1
আপনার উত্তরটি কীভাবে ব্যবহারকারীর1308743 উত্তর থেকে আলাদা ?
সের্গেই বেরেজোভস্কি

আমি কেবল একটি কাজের উদাহরণ ভাগ করে নিচ্ছিলাম। আমি এখানে যে সহায়তা পেয়েছি তার পিছনে দিতে আমি যা কিছু করতে পারি।
ব্রায়ান কুইন 0

-3

EF 6.2 এ এটি পুরোপুরি কাজ করে, ডিলিটটি সরাসরি সত্তা লোড না করে সরাসরি ডাটাবেসে প্রেরণ করে:

context.Widgets.Where(predicate).Delete();

একটি স্থির পূর্বাভাস সহ এটি বেশ সোজা:

context.Widgets.Where(w => w.WidgetId == widgetId).Delete();

এবং যদি আপনার একটি গতিশীল শিকারের প্রয়োজন হয় তবে লিনকুইকিট (নুগেট প্যাকেজ উপলভ্য) দেখুন, এরকম কিছু আমার ক্ষেত্রে ভাল কাজ করে:

Expression<Func<Widget, bool>> predicate = PredicateBuilder.New<Widget>(x => x.UserID == userID);
if (somePropertyValue != null)
{
    predicate = predicate.And(w => w.SomeProperty == somePropertyValue);
}
context.Widgets.Where(predicate).Delete();

1
কাঁচা ইএফ 6.2 দিয়ে এটি সম্ভব নয়। হয়তো আপনি ব্যবহার করছেন Z.EntityFramework.Plusবা অনুরূপ কিছু? ( অ্যান্টিফ্রেমওয়ার্ক.ট্যাব / ব্যাচ-ডিলিট )
স্যামি এস।

প্রথমটি হ'ল কাঁচা ইএফ 6.2 এবং কাজ সন্ধান করে। দ্বিতীয়টি হ'ল লিনককিট ব্যবহার করে আমি যেমন উল্লেখ করেছি।
ভ্লাদিমির

1
হুম, আমি এই পদ্ধতিটি খুঁজে পাচ্ছি না। এই পদ্ধতিটি কোন শ্রেণীর এবং কোন নামস্থানে রয়েছে তা আপনি পরীক্ষা করতে পারেন?
স্যামি এস।

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