thảo luận [Thảo Luận] Sử dụng Entity Framework thế nào cho sang

  • Người tạo chủ đề Người tạo chủ đề Pepe.The.Frog
  • Ngày bắt đầu Ngày bắt đầu
Mé dùng thằng Include của thằng EF hay dính vụ infinite loop giữa các entity có quan hệ, chuyển sang Projection vẫn dính đành phải dùng cái ngắt reference json :beat_shot:
 
Các bác cho em hỏi là thiết kế csdl thì sẽ thiết kế sẵn trong sql hay là dùng entity hết 100% vậy?
 
.Include(x => x.Where(..)) có mà bác, em cũng thử chạy rồi debug + check logging command nó cũng giảm đáng kể phần lấy ra, mình có thể Select trước rồi TolistAsync()
Miễn là chưa ToListAsync() thì các bé này chưa ra, vẫn chỉ là IQueryable
 
@Pepe.The.Frog

Em đang gặp vấn đề hiệu năng cho liên kết many to many nếu không dùng one to many, mong bác giải đáp ạ

Ví dụ 1 Post có nhiều Tag, 1 Tag cũng có nhiều Post. Em tạo 1 bảng PostTag làm trung gian
=> 1 Post có nhiều PostTag, 1 Tag có nhiều PostTag

Bây giờ khi em muốn tìm Post theo Tag thì có 2 cách
Cách 1:
SQL:
SELECT pt.PostId FROM PostTag pt
WHERE TagId = @tagId;

SELECT * FROM Posts WHERE Id IN (@postIds);

Cách 2:
SQL:
SELECT p.* FROM Posts p
JOIN PostTag pt ON p.Id = pt.PostId
WHERE pt.TagId = @tagId;


Em thấy rõ ràng cách 1, việc lấy ra hết PostTag theo postId và rồi lại sử dụng IN để lấy Post sẽ tốn rất nhiều tài nguyên, bình thường bác xử lý trường hợp này như thế nào vậy ạ
 
Sửa lần cuối:
Làm thì nói về hiệu suất, chứ nói sang vs hèn là thế méo nào :(
Nhưng cách của bác đấy phải nói thực sự rất ổn về hiệu suất, việc loại bỏ lazy load để tránh n + 1 command, bỏ quan hệ 1 - n để tránh lấy thừa dữ kiện trường hợp không cần thiết, quên hàm include rất hay

Tuy nhiên nếu bỏ quan hệ 1-n em thấy rất mệt khi dùng DDD (chỉ xoay quanh aggreagateRoot) hay Generic Repository (dùng thư viện, chỉ có thể join bằng lệnh include)
 
Nhưng cách của bác đấy phải nói thực sự rất ổn về hiệu suất, việc loại bỏ lazy load để tránh n + 1 command, bỏ quan hệ 1 - n để tránh lấy thừa dữ kiện trường hợp không cần thiết, quên hàm include rất hay

Tuy nhiên nếu bỏ quan hệ 1-n em thấy rất mệt khi dùng DDD (chỉ xoay quanh aggreagateRoot) hay Generic Repository (dùng thư viện, chỉ có thể join bằng lệnh include)
Cái nào cũng có tác dụng cả, include là khi muốn lấy thêm item con, lazy loading dùng để load item khi cần thiết.
Tôi chưa thấy cái nào là vô dụng cả, tránh lấy thừa thì select những thuộc tính cần lấy thôi :(
Vốn dĩ entity framework nó là repository rồi bạn ạ
 
Cái nào cũng có tác dụng cả, include là khi muốn lấy thêm item con, lazy loading dùng để load item khi cần thiết.
Tôi chưa thấy cái nào là vô dụng cả, tránh lấy thừa thì select những thuộc tính cần lấy thôi :(
Như bác @Pepe.The.Frog là muốn tránh những lỗi tiềm tàng, ảnh hưởng đến hiệu năng, em đã từng rất gà như bác ấy nói nên hiểu

Ban đầu em tham tái sử dụng, ko phải viết nhiều, có 1 câu query, cứ include hết vào, lấy thì lấy hết ra, xong sau map sang DTO để trả về. Viết code chỉ quan tâm gọi hàm này thì lấy được dữ liệu như thế này, thế kia, chẳng quan tâm nó gen ra SQL ra sao => Bỏ việc map 1 - n, lazy load sẽ giảm được đáng kể lỗi do những người như em tạo ra

Vốn dĩ entity framework nó là repository rồi bạn ạ

Sau khi đọc thớt Repository pattern là bullsh*t cũng của bác pepe, em cũng ngộ ra. Nhưng lỡ config project theo repository pattern như eshopweb của microsoft rồi, giờ sửa lại rất cực, đâm lao phải theo lao thôi =((
 
Thực sự những thớt của bác pepe đối với những lập trình viên gà mờ như em ý nghĩa vô cùng. Ban đầu em chỉ xem tutorial trên mạng, đọc source code người khác rồi học theo, rồi biết được kiến trúc, pattern có tác dụng này, kia nên sử dụng như một con vẹt.

Tuy nhiên sau khi thẩm hết các thớt của bác pepe, em đã quay lại, tìm hiểu kĩ từng dòng code mình viết, phân tích hết các ưu nhược điểm của các cách mình đang làm em cảm giác như đi lên 1 level mới, em đội ơn bác @Pepe.The.Frog vô cùng, mong bác ra nhiều thớt hơn, cho dù cả thế giới quay lưng lại với bác em vẫn sát cánh bên bác
 
Thực sự những thớt của bác pepe đối với những lập trình viên gà mờ như em ý nghĩa vô cùng. Ban đầu em chỉ xem tutorial trên mạng, đọc source code người khác rồi học theo, rồi biết được kiến trúc, pattern có tác dụng này, kia nên sử dụng như một con vẹt.

Tuy nhiên sau khi thẩm hết các thớt của bác pepe, em đã quay lại, tìm hiểu kĩ từng dòng code mình viết, phân tích hết các ưu nhược điểm của các cách mình đang làm em cảm giác như đi lên 1 level mới, em đội ơn bác @Pepe.The.Frog vô cùng, mong bác ra nhiều thớt hơn, cho dù cả thế giới quay lưng lại với bác em vẫn sát cánh bên bác
Số đá còn lại giấu ở đâu?
 
project hiện tại override SaveChanges để xem cái ChangeTracking rồi insert record vô audit database, hệ quả là audit bị tight coupling với SaveChanges, giờ audit bị chậm, không gọi nhiều thread để chạy concurrency được luôn :ops:
 
C#:
List<Blog> blogs = await bloggingContext.Blogs
    .Where(x => x.Url.Contains("voz"))
    .Include(x => x.Posts)
    .ToListAsync();

foreach (Blog blog in blogs)
{
    Console.WriteLine(blog.Url);
    foreach (Post post in blog.Posts)
    {
        Console.WriteLine(post.Title);
    }
}
Nếu thêm Include như vậy thì trong loop sẽ không hit database nữa
 
coi đẩy vào interceptor rồi bắn event xử riêng dc ko bác
em move code audit qua background service rồi bác, dùng chung với concurrent queue, khi nào cần audit thì bỏ object vô queue này rồi background service audit từ từ :smile:

để em search tham khảo thử cái interceptor là gì, trước giờ chưa nghe qua cái này luôn, cảm ơn bác nhé :byebye:
 
Sửa lần cuối:

Thống kê chủ đề

Ngày tạo
Pepe.The.Frog,
Người trả lời cuối
slowly_but_steadily,
Trả lời
81
Lượt xem
10.218
Quay lại
Lên đầu trang