Chẳng nhẽ bác viết một đống class cho các table thì bác lại cứ mỗi class viết CRUD trong đó???ủa tưởng bàn ORM mà cuối cùng chỉ gói gọn EF thui hả?
ủa tưởng bàn ORM mà cuối cùng chỉ gói gọn EF thui hả?
ý a nói cái gì?Chẳng nhẽ bác viết một đống class cho các table thì bác lại cứ mỗi class viết CRUD trong đó???
ý a nói cái gì?
đang nói thằng thớt đặt tít rõ general giờ cái gì cũng toàn lấy vd c# asp.net EF ra
thấy ở đâu? pattern là concept mà mấy ông thần?Thấy Repo Pattern với N-tier có trong mỗi .Net mà bác.
Anh Ếch cứ chửi vì bài toàn của ảnh ko cần Repository, còn của người khác lại cần. Dù EF nó implement sẵn nhưng đôi khi tự build cái Repository khác wrap ngoài lại dễ làm thêm những cái khác. Đơn giản như dự án của tôi, ở phần Repository các query của bọn tôi cần build thêm 1 số default param, và nó centralize ở cái repo đó thôi, ko muốn phải viết lại ở đống service. Hơn nữa nó liên quan đến bài toàn caching, cái Cache provider của của thằng EF nó ko đáp ứng dc, nên chúng tôi xử lý cache luôn ở Repository. Những thứ này có thể xử lý trong cái DbContext, nhưng nó phức tạp hơn việc bọn tôi xử lý ở thằng Repo
Mặt khác chúng tôi cũng ko muốn ở phía service nó access vào cái DbContext. Tôi đọc cái đoạn anh bảo review code để cấm dev làm cái này, tôi cười vl. Như anh gì trên kia bảo, thế cần đéo access modifier, cần đéo gì interface contract.
Anh cứ nhìn qua cái giếng của anh, thì anh còn thấy nhiều cái thối nữa
Các anh còn trẻ nên khi các anh bắt đầu code, các anh tiếp cận với EF và vì thằng EF nó làm việc theo cách của nó như các anh đang thấy. Và các anh nghĩ nó là cả thế giới.
Rồi các anh quay lại chửi Repository Pattern như các hàm GetById, GetByName là ko cần thiết. Các anh đang bắn đại bác vào lịch sử phát triển phần mềm với tri kiến của các anh đấy.
Tui đã đưa ví dụ với NHibernate Session rồi. Các anh muốn biết thì thử học nó đi. Khi các anh làm việc với NHibernate Session thì các anh mới hiểu thế nào là Unit Of Work.
Và vì là Unit Of Work nên cần các hàm GetById để gói gọn và chấm dứt
Session/Transaction trong một Unit Of Work để nó không ảnh hưởng đến các tác vụ khác.
Tui ko phải chuyên gia Ef, nhưng hồi còn làm NHibernate thì trong 1 UnitOfWork tôi có thể gởi đồng thời nhiều query lên server cùng một thời điểm để tránh round trip rất hay. Mà giờ già rồi ko nhớ nó gọi là gì.
Và đó là cách làm việc của các ORM thời đó. (Và bây giờ?)
. Cho tới khi thằng EF ra đời. Nó hoạt động theo một cách hoàn toàn khác để tracking changes của Entity và loại bỏ khái niệm Session (hoặc nó có internal Session tui ko rành) nên Unit Of Work nó ko có ý nghĩa trong EF.
Một cái khác biệt lớn nhất khi làm việc với Ef là Repository không khởi tạo Singleton được. Trong khi NHibernate thì tạo Singleton Repository bình thường.
Các anh em làm Python, Php,... có thể chia sẻ Orm bên các ngôn ngữ đó hoạt động như thế nào? Nhưng tui đoán các anh em vẫn sẽ cần Repository Pattern với GetById hay GetByName.
Edit: Định trả lời anh Ếch ở dưới mà nghĩ. Đọc tới dòng addscoped inject vào singleton instance, tôi lắc đầu. Chắc hi vọng nó sẽ tự tạo instance mới của DbContext bằng phép màu. Rồi multi-theading kiểu gì, muli-user, parallel editing kiểu gì. Thôi tốn thời gian vô ích nên tui out topic. Bye bye anh em.
Bác nói chuẩn, một số bác chưa hiểu đúng về repo nên cãi cùn, các bác nào chưa hiểu đúng thì làm ơn ngồi đó nghe giải thích hoặc lên youtube coi nhé. Chứ đừng vác orm mang ra so sánh với repo design pattern.Anh Ếch cứ chửi vì bài toàn của ảnh ko cần Repository, còn của người khác lại cần. Dù EF nó implement sẵn nhưng đôi khi tự build cái Repository khác wrap ngoài lại dễ làm thêm những cái khác. Đơn giản như dự án của tôi, ở phần Repository các query của bọn tôi cần build thêm 1 số default param, và nó centralize ở cái repo đó thôi, ko muốn phải viết lại ở đống service. Hơn nữa nó liên quan đến bài toàn caching, cái Cache provider của của thằng EF nó ko đáp ứng dc, nên chúng tôi xử lý cache luôn ở Repository. Những thứ này có thể xử lý trong cái DbContext, nhưng nó phức tạp hơn việc bọn tôi xử lý ở thằng Repo
Mặt khác chúng tôi cũng ko muốn ở phía service nó access vào cái DbContext. Tôi đọc cái đoạn anh bảo review code để cấm dev làm cái này, tôi cười vl. Như anh gì trên kia bảo, thế cần đéo access modifier, cần đéo gì interface contract.
Anh cứ nhìn qua cái giếng của anh, thì anh còn thấy nhiều cái thối nữa
Microsoft cũng nói return IQueryable phá vỡ cấu trúc Repo.Nhiều khi các anh cũng nên nhìn xuống giếng xem nó có con ếch ở đó ấy
Anyway, tôi chỉ phản đối vụ Generic Repository implement sai đi public cái IQueryable ra thôi. Còn giờ tôi lượn đây.
A key point to note is that our GetAllBlogs method returns IEnumerable<Blog>, and not IQueryable<Blog>. Returning the latter would mean that query operators can still be composed over the result, requiring that EF Core still be involved in translating the query; this would defeat the purpose of having a repository in the first place
bác thớt cho mình hỏi, vd trong case này khi áp dụng cho Laravel:Tôi hiểu cái mô hình của a đang là như này:
Controllers -> Services -> Repositories -> ORM
Còn theo tôi nó nên là như này:
Controllers -> Services -> ORM
Lý do tôi chửi là vì tôi thấy rất nhiều dự án đã xài ORM rồi còn chèn thêm thằng Repositories bên trên như anh với rất nhiều lý do mơ hồ đưa ra nhưng khi tôi xoáy vào cụ thể vì sao mô hình phía dưới ko đáp ứng đc thì chẳng ai trả lời dc.
Khi nào rảnh thì a demo 1 phát cho tôi mở mang tầm mắt chứ gặp Vozer ngoài đời ngại lắm, ko dám gặp đâu.
bác thớt cho mình hỏi, vd trong case này khi áp dụng cho Laravel:
Controllers -> Services -> ORM
Mình có thể dùng trực tiếp ORM trong Controller hay ko ? hay bắt buộc phải đưa nó vào Services. Mình hiểu Service là nơi chưa business logic của application, nhưng nếu chức năng chỉ đơn giản như hiển thị danh sách users(getListUsers()) thì nên dùng trực tiếp ở Controllers hay viết trong Services ? Tương tự, nếu mình có thêm 1 chức năng dạng như send email, trong Laravel thường thì sẽ tạo SendEmailJob class để đưa vào queue. Nếu áp dụng pattern trên thì chẳng hạn trong SendEmailJop cần tương tác vs ORM để lấy data thì cũng call Services -> ORm hay dụng trực tiếp ORM trong đó luôn ạ
Vậy trong trường hợp 2 Service cần dùng chung 1 method thì sao nhỉ ? vd trong PostService cần lấy danh sách users. Trong UserService đã có sẵn hàm getListUsers(). Trong trường hợp này mình nên handle ntn ạ ? Trong PostService, gọi UserService->getListUsers() ? hay lại tách nó ra thêm 1 class khác(Helpers) ?Nên đưa vào services, tất nhiên nếu muốn code 1 layer, xài trực tiếp trên controllers thì cũng được nhưng làm dạng chơi chơi chứ project thực tế ko khuyến khích.
Nên tách biệt 2 phần là presentation và logic ra để có gì unit test cả 2, hoặc đổi tầng presentation thì service vẫn ko đổi vì dù sao service mới là core của application.
Vậy trong trường hợp 2 Service cần dùng chung 1 method thì sao nhỉ ? vd trong PostService cần lấy danh sách users. Trong UserService đã có sẵn hàm getListUsers(). Trong trường hợp này mình nên handle ntn ạ ? Trong PostService, gọi UserService->getListUsers() ? hay lại tách nó ra thêm 1 class khác(Helpers) ?
Thì gọi cross service bình thường chứ có gì đâuVậy trong trường hợp 2 Service cần dùng chung 1 method thì sao nhỉ ? vd trong PostService cần lấy danh sách users.
Có ai giải quyết dc T/H này của mình ko, mình chỉ muốn select các fields cần thiết ( select loading) để đảm bảo perf nhưng repo partern chỉ nên trả về nguyên cái domain class chứ ko phải DTO.Microsoft cũng nói return IQueryable phá vỡ cấu trúc Repo.
A key point to note is that our GetAllBlogs method returns IEnumerable<Blog>, and not IQueryable<Blog>. Returning the latter would mean that query operators can still be composed over the result, requiring that EF Core still be involved in translating the query; this would defeat the purpose of having a repository in the first place
https://docs.microsoft.com/en-us/ef/core/testing/testing-without-the-database
Ngoài ra mình cũng hỏi là trong t/h dùng repo, nếu câu query mình muốn select field cần thiết, ko select all domain thì phải làm sao.
Thanks
Vậy thì sẽ gặp trường hợp các services bị lồng nhau mình chưa gặp trường hợp này bao giờ, nhưng nghe nói là nên tránhThì gọi cross service bình thường chứ có gì đâu
Bác có thể nói thêm 1 xíu về vấn đề này được khôngTrường hợp này có 3 cách:
1. Là dùng 3 layers, dùng Repository (DDD) để gom cái logic đó xài chung cho nhiều services
2. Tạo extension methods, helper hay cái gì đó tương tự C# cho bên PHP.
3. Gọi cross-services, service call service. Cách này thì phải chú ý chổ quản lý transaction để đảm bảo sopce của nó đúng như mong đợi vì nó gọi lồng nhau
Chọn cách nào là tuỳ vào implement hiện tại của dự án.
Có ai giải quyết dc T/H này của mình ko, mình chỉ muốn select các fields cần thiết ( select loading) để đảm bảo perf nhưng repo partern chỉ nên trả về nguyên cái domain class chứ ko phải DTO.
Làm sao ko phá vỡ patern mà vẫn thỏa mãn yêu cầu của mình vậy.