Làm thế nào để buộc Entity Framework luôn nhận được dữ liệu cập nhật từ cơ sở dữ liệu?


87

Tôi đang sử dụng thư viện EntityFramework.Extended để thực hiện cập nhật hàng loạt. Vấn đề duy nhất là EF không theo dõi các cập nhật hàng loạt do thư viện thực hiện. Vì vậy, khi tôi truy vấn DbContextlại nó không trả về các thực thể đã cập nhật.

Tôi nhận thấy rằng việc sử dụng AsNoTracking()phương pháp trong khi truy vấn sẽ tắt theo dõi và nhận dữ liệu mới từ cơ sở dữ liệu. Tuy nhiên, vì EF không theo dõi các thực thể được truy vấn AsNoTracking()nên tôi không thể thực hiện bất kỳ cập nhật nào đối với dữ liệu được truy vấn.

Có cách nào để buộc EF nhận dữ liệu mới nhất trong khi theo dõi các thay đổi không?


2
29k lượt xem và chỉ có 19 lượt ủng hộ về điều này ...
à,

Câu trả lời:


148

Vui lòng thử cách này để làm mới một thực thể:

Context.Entry<T>(entity).Reload()

Chỉnh sửa: Để có được dữ liệu mới cho một tập hợp các thực thể, bạn nên thử loại bỏ DbContextcá thể sau mỗi lần yêu cầu.


Cảm ơn bạn! Có cách nào để tải lại một tập hợp các thực thể thay vì một? Tốt nhất là toàn bộ DbSet.
Saravana

Có điều gì khác bạn cần để điều này được coi là câu trả lời?
PlTaylor

1
Có, nó vẫn không hiển thị cách tải lại một tập hợp các thực thể.
Saravana

1
Bạn đã thử loại bỏ dbcontext của mình và tạo một cái mới chưa?
PlTaylor

2
Tôi đã mất hàng giờ để đi đến kết luận này. Đó EDIT trong câu trả lời là những gì giúp tôi tìm thấy giải pháp của tôi. Cảm ơn!
BeemerGuy

17

Tôi tình cờ gặp câu hỏi này trong khi tìm kiếm giải pháp cho vấn đề tôi đang gặp phải trong đó các thuộc tính điều hướng không được điền sau khi cập nhật thực thể. Bất cứ khi nào tôi cố gắng tải lại thực thể từ cơ sở dữ liệu, nó sẽ lấy mục nhập từ cửa hàng cục bộ thay vào đó sẽ không điền các thuộc tính điều hướng thông qua tải chậm. Thay vì phá hủy ngữ cảnh và tạo lại ngữ cảnh, tôi thấy điều này cho phép tôi nhận dữ liệu mới với các proxy đang hoạt động:

_db.Entry(entity).State = EntityState.Detached;

Logic đằng sau nó là - bản cập nhật của tôi đã đính kèm thực thể để nó theo dõi các thay đổi đối với nó. Điều này thêm nó vào cửa hàng địa phương. Sau đó, bất kỳ nỗ lực nào để truy xuất thực thể bằng các proxy chức năng sẽ dẫn đến việc nó lấy thực thể cục bộ thay vì đi ra db và trả về một thực thể mới, hỗ trợ proxy. Tôi đã thử tùy chọn tải lại ở trên, tùy chọn này làm mới đối tượng từ cơ sở dữ liệu, nhưng điều đó không cung cấp cho bạn đối tượng được ủy quyền với tính năng tải chậm. Tôi đã thử làm a Find(id), Where(t => t.Id = id), First(t => t.Id = id). Cuối cùng, tôi đã kiểm tra các trạng thái có sẵn đã được cung cấp và thấy có trạng thái "Đã tách rời". Eureka! Hy vọng điều này sẽ giúp ai đó.


Làm ơn áp dụng trạng thái tách rời để tải lười hoạt động ở đâu? Tôi đã thử giải pháp của bạn và nó không hiệu quả với tôi, tôi phải bỏ lỡ điều gì đó. Giúp đỡ của bạn sẽ được đánh giá
Rex

2
Tôi đã tìm ra nó: 1. lưu thực thể, 2. đặt trạng thái thành tách rời, 3. đọc thực thể từ db. Cảm ơn vì gợi ý!
Rex

1

Làm cho mã chạy trên cùng một ngữ cảnh sẽ không mang lại cho bạn các thực thể được cập nhật. Nó sẽ chỉ nối các thực thể mới được tạo trong cơ sở dữ liệu giữa các lần chạy. Tải lại lực EF có thể được thực hiện như sau:

ObjectQuery _query = Entity.MyEntity;
_query.MergeOption = MergeOption.OverwriteChanges;
var myEntity = _query.Where(x => x.Id > 0).ToList();

1

Tôi đã khai báo biến thực thể, không có phép gán, như một phần của lớp. Điều này cho phép tôi loại bỏ một cá thể mà không làm mất biến để tham chiếu bởi các phương thức khác. Tôi vừa xem qua điều này nên nó không có nhiều thời gian chạy, nhưng cho đến nay nó có vẻ hoạt động tốt.

public partial class frmMyForm
{
    private My_Entities entity;

    public frmMyForm()
    {
        InitializeComponent();
    }

    private void SomeControl_Click(object sender, EventArgs e)
    {
        db.SaveChanges();
        db.Dispose();
        entity = new My_Entities();
        //more code using entity ...
}

0

Đối với tôi ... tôi truy cập DbContext của mình như thế này:

_viewModel.Repo.Context

Để buộc EF đánh vào cơ sở dữ liệu, tôi làm như sau:

_viewModel.Repo.Context = new NewDispatchContext();

Ghi đè DbContext hiện tại bằng một phiên bản mới. Sau đó, lần tiếp theo tôi sử dụng các dịch vụ dữ liệu của mình, họ sẽ lấy dữ liệu từ cơ sở dữ liệu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.