2012-01-17 42 views
8

TLDR; Làm thế nào để đọc dữ liệu từ một bảng sử dụng Entity Framework, khi tên bảng không được biết tại thời gian biên dịch?Truy vấn dữ liệu bằng cách sử dụng Khung thực thể từ bảng được tạo động

Có một hệ thống bên ngoài xử lý một lượng lớn thông tin, sau đó tạo một bảng mới cho mỗi đợt chạy và lưu trữ một số dữ liệu trong bảng đó. Bố trí cột của các bảng mới này được biết trước, vì vậy tôi đã tạo ra một ADO.NET Entity Data Model (tệp edmx) từ cơ sở dữ liệu hiện có, trong đó có một bảng có bố cục cột chính xác giống nhau.

Bảng gốc trong cơ sở dữ liệu đó được gọi là ResultTableTemplate, do đó lớp thực thể đại diện cho bảng đó cũng được gọi là ResultTableTemplate.

Tôi đang cố gắng tìm hiểu cách sử dụng Mô hình dữ liệu thực thể ADO.NET của mình để đọc từ các bảng được tạo động đó và quay lại IEnumerable<ResultTableTemplate>. Những gì tôi đã làm cho đến nay đây là:

public IEnumerable<ResultTableTemplate> GetResultsFromTable(string tableName) { 
    using (var context = new WorkdataEntities()) { 
     var table = context.CreateQuery<ResultTableTemplate>("SELECT " + 
      "ALL_THOSE_COLUMN_NAMES... " + 
      "FROM " + tableName; 

     var query = from item in table select item; 

     return query.ToList(); 
    } 
} 

Khi tôi chạy truy vấn, tôi nhận được một System.Data.EntitySqlException với thông báo sau:

'ResultTable419828' không thể được giải quyết trong phạm vi hiện tại hoặc bối cảnh. Đảm bảo rằng tất cả biến được tham chiếu nằm trong phạm vi, rằng các lược đồ bắt buộc được tải và các không gian tên đó được tham chiếu chính xác. biểu hiện gần thành viên truy cập, dòng 1, cột 225.

ResultTable419828 là giá trị của tableName

Tôi đã thử tableName + " AS ResultTableTemplate" nhưng nó đã không giúp đỡ.

Có cách nào chuyển tiếp cho tôi hay tôi sẽ phải thực hiện việc này nếu không có sự trợ giúp của Khung thực thể?

EDIT: Tôi nhận ra bây giờ mà nội dung truy vấn Tôi viết thư này không được thông qua tất cả các con đường xuống dụ SQL Server cơ bản, nhưng được giải thích bởi Entity Framework trả về một thể hiện ObjectQuery<ResultTableTemplate>, vì vậy nó trông cho ResultTable419828 trong các trường hợp DbSet được tạo tự động của Ngữ cảnh.

Tuy nhiên, có cách nào để tôi đạt được những gì tôi cần làm không?

EDIT: Cảm ơn Ladislav Mrnka. Bây giờ, tôi làm điều này:

public IEnumerable<ResultTableTemplate> GetResultsFromTable(string tableName) { 
    using (var context = new WorkdataEntities()) { 
     var query = context.ExecuteStoreQuery<ResultTableTemplate>("SELECT " + 
      "ALL_THOSE_COLUMN_NAMES... " + 
      "FROM " + tableName; 

     return query.ToList(); 
    } 
} 
+1

Tôi nghĩ rằng đó là tạo một EntityQuery, không phải là truy vấn cơ sở dữ liệu. Do đó TỪ là một DbSet không phải là một bảng cơ sở dữ liệu. – cadrell0

+0

'CreateQuery ()' trả về một 'ObjectQuery ' - và bây giờ tôi thấy rằng bạn đã đúng. Truy vấn không chống lại một bảng cơ sở dữ liệu, mà là một DbSet. Bạn có nghĩ rằng có một cách để làm những gì tôi cần phải làm ở đây? –

+0

Chúng tôi sử dụng một DbConnection với SqlQuery để có được một giá trị vô hướng từ cơ sở dữ liệu. Tôi đã không viết phần đó của DAL của chúng tôi, vì vậy tôi không hoàn toàn chắc chắn như thế nào nó hoạt động, nhưng bạn có thể có thể bắt đầu ở đó. – cadrell0

Trả lời

11

Không thể trực tiếp thực hiện được. Khi bạn ánh xạ thực thể đến ResultTableTemplate, bạn hãy mã hóa tên của bảng cho thực thể này. Các thực thể có thể được ánh xạ chỉ một lần (trên mỗi mô hình) để khi chạy mỗi truy vấn EF cho thực thể này luôn dẫn đến truy vấn tới bảng ResultTableTemplate.

Cách duy nhất để thay đổi là hành vi đang sửa đổi tệp ánh xạ (SSDL) khi chạy khá xấu xí vì nó yêu cầu bạn thay đổi tệp XML và tải lại tệp. Bạn sẽ phải xây dựng MetadataWorkspace theo cách thủ công mỗi khi bạn thay đổi tệp. Xây dựng MetadataWorkspace là một trong những hoạt động tiêu thụ hiệu quả nhất trong EF. Trong chạy bình thường MetadataWorkspace chỉ được tạo một lần cho mỗi lần chạy ứng dụng.

Có cách giải quyết đơn giản. Bạn biết tên bảng và bạn biết cấu trúc bảng - nó được cố định. Vì vậy, sử dụng SQL trực tiếp và sử dụng EF trở thành hiện thực kết quả vào lớp thực thể ánh xạ của bạn:

var table = context.ExecuteStoreQuery<ResultTableTemplate>("SELECT ... FROM " + tableName); 

Những bất lợi là bạn không thể sử dụng LINQ trong cách tiếp cận này, nhưng yêu cầu của bạn không phải là rất phù hợp cho EF.

0

Hãy thử điều này; :)

string tableName = "MyTableTest"; 

// Fetch the table records dynamically 
var tableData = ctx.GetType() 
       .GetProperty(tableName) 
       .GetValue(ctx, null); 
+1

Bạn có thể trình bày cách bạn truy vấn bảng. – Talon

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