EF 6 - Truy vấn trong EF 6
Truy vấn trong Entity Framework
Bạn có thể xây dựng và thực hiện các truy vấn bằng Entity Framework để lấy dữ liệu từ cơ sở dữ liệu. Entity Framework 6 hỗ trợ các loại truy vấn khác nhau lần lượt chuyển đổi thành truy vấn SQL cho cơ sở dữ liệu.
Entity Framework hỗ trợ ba loại truy vấn:
- LINQ-to-Entities
- Entity SQL
- Truy vấn SQL
Truy vấn LINQ-to-Entities
Truy vấn tích hợp ngôn ngữ (LINQ) là ngôn ngữ truy vấn mạnh mẽ được giới thiệu trong Visual Studio 2008.
Như tên gọi của nó, các truy vấn LINQ-to-Entities hoạt động trên tập thực thể (thuộc tính kiểu DbSet
) để truy cập dữ liệu từ cơ sở dữ liệu. Bạn có thể sử dụng cú pháp phương thức hoặc cú pháp truy vấn LINQ khi truy vấn với EDM.
Truy vấn LINQ-to-Entities sau đây lấy dữ liệu từ bảng Student
trong cơ sở dữ liệu.
Cú pháp phương thức LINQ:
using (var context = new SchoolDBEntities())
{
var query = context.Students
.Where(s => s.StudentName == "Bill")
.FirstOrDefault<Student>();
}
Cú pháp truy vấn LINQ:
using (var context = new SchoolDBEntities())
{
var query = from st in context.Students
where st.StudentName == "Bill"
select st;
var student = query.FirstOrDefault<Student>();
}
Như bạn có thể thấy ở trên, chúng tôi đã tạo một thể hiện của lớp Context SchoolDBEntities
. Bạn nên khởi tạo nó sử dụng using()
để sau đi ra khỏi phạm vi khối using
nó sẽ tự động được hủy và giải phóng bộ nhớ (disposed).
Entity SQL
Entity SQL là một cách khác để tạo một truy vấn. Nó được xử lý trực tiếp bởi Dịch vụ đối tượng của Entity Framework. Nó trả về ObjectQuery thay vì IQueryable.
Bạn cần một đối tượng ObjectContext
để tạo một truy vấn bằng cách sử dụng Entity SQL.
Đoạn mã sau đây cho thấy kết quả truy vấn tương tự như truy vấn LINQ ở trên.
string sqlString = "SELECT VALUE st FROM SchoolDBEntities.Students " +
"AS st WHERE st.StudentName == 'Bill'";
var objctx = (ctx as IObjectContextAdapter).ObjectContext;
ObjectQuery<Student> student = objctx.CreateQuery<Student>(sqlString);
Student newStudent = student.First<Student>();
Bạn cũng có thể sử dụng EntityConnection
và EntityCommand
để thực thi Entity SQL như dưới đây:
using (var con = new EntityConnection("name=SchoolDBEntities"))
{
con.Open();
EntityCommand cmd = con.CreateCommand();
cmd.CommandText = "SELECT VALUE st FROM SchoolDBEntities.Students as st where st.StudentName='Bill'";
Dictionary<int, string> dict = new Dictionary<int, string>();
using (EntityDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.CloseConnection))
{
while (rdr.Read())
{
int a = rdr.GetInt32(0);
var b = rdr.GetString(1);
dict.Add(a, b);
}
}
}
Truy vấn SQL
Bạn có thể thực thi các truy vấn SQL gốc cho cơ sở dữ liệu quan hệ, như được trình bày bên dưới:
using (var ctx = new SchoolDBEntities())
{
var studentName = ctx.Students
.SqlQuery("Select studentid, studentname, standardId from Student where studentname='Bill'")
.FirstOrDefault<Student>();
}
Thực hiện các truy vấn SQL trong Entity Framework
Entity Framework cho phép bạn thực hiện các truy vấn SQL cho cơ sở dữ liệu quan hệ.
Các phương thức sau đây có thể được sử dụng để thực thi các truy vấn SQL vào cơ sở dữ liệu bằng Entity Framework 6.x:
- DbSet.SqlQuery()
- DbContext.Database.SqlQuery()
- DbContext.Database.ExecuteSqlCommand()
DbSet.SqlQuery()
Sử dụng phương thức DbSet.SqlQuery()
để viết các truy vấn SQL trả về các thể hiện của thực thể. Các thực thể trả về sẽ được theo dõi bởi Context, như thể chúng được trả về bởi truy vấn LINQ.
using (var ctx = new SchoolDBEntities())
{
var studentList = ctx.Students
.SqlQuery("Select * from Students")
.ToList<Student>();
}
Truy vấn trên thực thi câu lệnh SQL Select * from Students
trong cơ sở dữ liệu để trả về tất cả sinh viên và được chuyển đổi thành một danh sách các thực thể Student
. Tên cột trong truy vấn SQL phải khớp với các thuộc tính của kiểu thực thể, nếu không nó sẽ đưa ra một ngoại lệ.
Bạn có thể chỉ định các tham số bằng cách sử dụng đối tượng SqlParameter
, như sau:
using (var ctx = new SchoolDBEntities())
{
var student = ctx.Students
.SqlQuery("Select * from Students where StudentId=@id",
new SqlParameter("@id", 1))
.FirstOrDefault();
}
Nếu bạn thay đổi tên cột trong truy vấn SQL, thì nó sẽ đưa ra một ngoại lệ vì nó phải khớp với tên cột. Ví dụ sau đây sẽ đưa ra một ngoại lệ.
using (var ctx = new SchoolDBEntities())
{
//this will throw an exception
var studentName = ctx.Students.SqlQuery("Select studentid as id, studentname as name from Student where studentname='Steve'").ToList();
}
Phương thức DbSet<TEntity>.SqlQuery()
thực hiện truy vấn SQL chỉ dành cho bảng được ánh xạ với thực thể được chỉ định (ví dụ: DbSet<Student>.SqlQuery()
chỉ trả về kết quả từ bảng Students
tương ứng chứ không phải từ bất kỳ bảng nào khác). Sau đây sẽ ném một ngoại lệ.
using (var ctx = new SchoolDBEntities())
{
//this will throw an exception
var studentName = ctx.Students.SqlQuery("Select * from Courses").ToList();
}
Database.SqlQuery()
Lớp Database
đại diện cho cơ sở dữ liệu và cung cấp phương thức khác nhau để truy vấn cơ sở dữ liệu. Phương thức Database.SqlQuery()
trả về một giá trị của bất kỳ kiểu dữ liệu nào.
using (var ctx = new SchoolDBEntities())
{
//Get student name of string type
string studentName = ctx.Database.SqlQuery<string>("Select studentname from Student where studentid=1")
.FirstOrDefault();
//or
string studentName = ctx.Database.SqlQuery<string>("Select studentname from Student where studentid=@id", new SqlParameter("@id", 1))
.FirstOrDefault();
}
Database.ExecuteSqlCommand()
Phương thức Database.ExecuteSqlCommnad()
rất hữu ích trong thực hiện các lệnh Insert, Update và Delete.
using (var ctx = new SchoolDBEntities())
{
int noOfRowUpdated = ctx.Database.ExecuteSqlCommand("Update student
set studentname ='changed student by command' where studentid=1");
int noOfRowInserted = ctx.Database.ExecuteSqlCommand("insert into student(studentname)
values('New Student')");
int noOfRowDeleted = ctx.Database.ExecuteSqlCommand("delete from student
where studentid=1");
}