2012-01-16 29 views
11

Tôi đang cố gắng thực hiện DELETE bằng LINQ sẽ tạo ra một truy vấn đơn lẻ.Xóa nhiều bản ghi với Khung thực thể bằng cách sử dụng một truy vấn LINQ duy nhất

Đây là cách tôi đang làm nó:

// NorthwintEntities is an ADO.NET Entitity Data Model 
var northwindEntities = new NorthwindEntities(); 
northwindEntities.Order_Details.Delete(o => o.Order_ID == 11076); 

Dưới đây là mở rộng của tôi:

public static class EntityExtensions 
{ 
    private static Regex rxTableName = new Regex(@"^FROM\s+(?<table>\[[^\]]*\](\.\[[^\]]*\]){0,2})\s+AS\s+(?<alias>\[[^\]]*\])", RegexOptions.Multiline); 

    public static void Delete<T>(this ObjectSet<T> entity, Expression<Func<T, bool>> expression) where T : EntityObject 
    { 
     var selectQuery = entity.Where(expression).Select(x => 1); 

     string selectQueryString = ((ObjectQuery)selectQuery).ToTraceString(); 

     string deleteQueryString = ConvertSqlSelectToDelete(selectQueryString); 

     entity.Context.ExecuteStoreCommand(deleteQueryString); 
    } 

    private static string ConvertSqlSelectToDelete(string selectQuery) 
    { 
     if (selectQuery.IndexOf(" JOIN ") > -1) 
     { 
      throw new Exception("Query with JOIN is not supported: " + selectQuery); 
     } 

     Match match = rxTableName.Match(selectQuery); 
     if (!match.Success) 
     { 
      throw new Exception("Unable to convert SELECT: " + selectQuery); 
     } 

     string deleteQuery = "DELETE \r\n" + selectQuery.Substring(match.Index); 
     deleteQuery = deleteQuery.Replace(match.Groups["alias"].Value + ".", ""); 
     deleteQuery = deleteQuery.Replace("AS " + match.Groups["alias"].Value, ""); 

     return deleteQuery; 
    } 
} 

này hoạt động, nhưng tôi có một vài ý kiến.

  • Tôi không phải là người hâm mộ lớn sử dụng Regex ở đây, nhưng đó là cách duy nhất để tôi lấy tên bảng. (entity.EntitySet.Name không phải lúc nào cũng trả lại tên đúng. [Chi tiết đơn đặt hàng] là một ví dụ).
  • Sau khi hoàn tất việc này, tôi thấy số này là http://msmvps.com/blogs/matthieu/archive/2010/05/21/bulk-delete-v3.aspx nhưng không thể làm việc đó được. Nhận được một NotImplementedException từ ngữ cảnh là null.
  • Xóa bằng tham gia dường như không hoạt động. Tôi đang thử nghiệm với SQL Server Compact 3.5, có lẽ đó là một hạn chế về điều đó.

Vì vậy, câu hỏi của tôi là: Có cách nào dễ dàng hơn để thực hiện việc này không? Nếu vậy, nó là cái gì?

Bất kỳ trợ giúp nào đều sẽ được đánh giá cao.

+4

Vui lòng xem [câu hỏi] [1]. [1]: http://stackoverflow.com/questions/8538899/ –

+0

Bạn đã xem xét RemoveRange trong EF6? Tôi muốn biết có bao nhiêu nó được "tối ưu hóa" và sql nó chạy. http://msdn.microsoft.com/en-us/library/system.data.entity.dbset.removerange(v=vs.113).aspx – Colin

+0

Lấy tên bảng từ siêu dữ liệu - http://stackoverflow.com/a/18964974/150342 – Colin

Trả lời

8
  1. Install Entity Framework mở rộng Thư viện (PM> Install-Package EntityFramework.Extended)

  2. EntityFramework.Extensions nhập trong mã của bạn

  3. Xóa hồ sơ theo quy định của truy vấn nội

    context.Orders.Where(o=>o.User_ID == 1).Delete(); 
    

Xóa tất cả các bản ghi bên trong Đơn đặt hàng có userID = 1

+0

Đó là vì vậy KHÔNG theo tinh thần của EntityFramework được giới hạn cho một nhà cung cấp cụ thể (SQL-Server). – springy76

5

Một cách để xóa hàng loạt là cài đặt TRÊN TRƯỜNG HỢP XÓA trên các khóa ngoại. Bạn cần phải thiết lập CASCADE về quan hệ trong thiết kế và thiết lập TRÊN TRƯỜNG HỢP DELETE về mối quan hệ trong cơ sở dữ liệu.

Để xóa sản phẩm Điều hướng sản phẩm từ Đơn đặt hàng EF sẽ thực hiện (số thuộc tính Sản phẩm) +1 câu lệnh cho cơ sở dữ liệu.

tôi thích để làm điều đó:

var order = context.Orders.Include(p=>p.Products).Where(o=>o.Order_ID == 11076); 

foreach(Product product in order.Products.ToList()) 
{ 
    context.Entry(product).State = EntityState.Deleted; 
} 
context.Entry(order).State = EntityState.Deleted; 
context.SaveChanges(); 

Hy vọng nó giúp.

+3

Khi di chuyển cho mục tiếp theo trong liệt kê, nó đi ra với lỗi "Mục sửa đổi từ danh sách, không thể tiến hành đếm thêm. – DOM

+0

Nó không hoạt động trong Entity v5 –

+0

Tôi không biết tại sao @DOM nói rằng nó không hoạt động. Nó hoạt động hoàn hảo tốt miễn là bạn không quên gọi ToList() phương pháp. – NoobDeveloper

Các vấn đề liên quan