Repositori EntityFramework, semua baris mengembalikan nilai nol

Ringkasan

Saya telah memodifikasi solusi nopCommerce untuk memasukkan Entitas baru dengan Pendekatan CodeFirst, telah berhasil memperbarui Database seperti yang ditunjukkan pada gambar di bawah ini.

Foto yang tabelnya telah diperbarui di database

Ketika saya mencoba mengakses tabel repositori, yang dimasukkan melalui AutoFrac, saya mendapatkan baris yang dikembalikan oleh repositori tetapi dengan semua kolom menunjukkan nilai nol. Perhatikan bahwa jumlah baris pada tabel sama dengan yang terlihat pada tabel database, sehingga seolah-olah sudah terhubung tetapi tidak menunjukkan nilainya.

Repositori panggilan kode

{
    public partial class NutrientService : INutrientService
    {
        #region fields

        protected readonly IRepository<ProductNutrient> _productNutrientRepository;

        #endregion fields

        #region Ctor

        public NutrientService(IRepository<ProductNutrient> productNutrientRepository)
        {
            _productNutrientRepository = productNutrientRepository;
        }

        #endregion Ctor

        public IList<ProductNutrient> GetNutrients()
        {
            var query = from p in _productNutrientRepository.Table
                        select p as ProductNutrient;
            var list = query.ToList();
            return list;
        }

        public IList<ProductNutrient> GetNutrientsByProductID()
        {
           
            var query = from p in _productNutrientRepository.Table
                        select p as ProductNutrient;
            var list = query.ToList();
            return list;
        }
    }
} 

Debugging menampilkan nilai Null yang dikembalikan dari repositori

Definisi Tabel di SQL Management Studio

Definisi Entitas dalam Kode

    public class ProductNutrient : BaseEntity
    {
        public int NutrientID;

        public int ProductID;

        public string Nutrient;

        public bool ShowLessThan;

        public decimal Value;

        public string Unit;
    }
}

Repositori berfungsi dengan tabel lain, tetapi ini kode repositorinya

      /// </summary>
        public virtual IQueryable<TEntity> Table => Entities;

        /// <summary>
        /// Gets an entity set
        /// </summary>
        protected virtual ITable<TEntity> Entities => _entities ?? (_entities = _dataProvider.GetTable<TEntity>());


        #endregion
    }

person DanCRichards    schedule 06.01.2021    source sumber
comment
Tolong jangan memposting kode dan hasil sebagai gambar. Mereka tidak dapat disalin (sebagian) untuk dijawab dan teksnya tidak akan muncul di mesin pencari. Gambar hanya boleh digunakan sebagai pilihan terakhir.   -  person Gert Arnold    schedule 07.01.2021
comment
Diperbarui terima kasih. Ini adalah posting pertama saya ke SO. Saya harap Anda juga dapat memberikan dukungan terkait masalah ini. Terima kasih Dan   -  person DanCRichards    schedule 07.01.2021
comment
select p as ProductNutrient; mungkin tidak sesuai dengan apa yang Anda pikirkan, p adalah hal lain. Mengapa Anda tetap melemparkannya? Namun repositori tersebut tidak terlihat oleh kami (khususnya ada apa di balik _productNutrientRepository.Table) dan, tetap saja, pertanyaan dapat diajukan tanpa semua gambar.   -  person Gert Arnold    schedule 07.01.2021
comment
Saya bertanya-tanya apa ini _productNutrientRepository.Table? Bisakah Anda menunjukkan kepada kami kode _productNutrientRepository dan kode Tabel?   -  person Serge    schedule 07.01.2021
comment
Hai @Sergey, saya telah memperbarui postingan untuk menunjukkan ini. Ada layanan lain di proyek saya yang mereferensikan antarmuka repositori dan berfungsi dengan baik. Saya sedikit bingung mengapa _productNutrientRepository.Table menampilkan item dalam daftar, tetapi dengan nilai nol. Juga terjadi ketika saya memasukkan nilai, itu hanya membuat catatan nol.   -  person DanCRichards    schedule 07.01.2021
comment
@GertArnold Anda mungkin tidak perlu khawatir untuk membantu saya dalam hal ini, terima kasih!   -  person DanCRichards    schedule 07.01.2021


Jawaban (1)


Saya curiga Anda tersesat dalam abstraksi, atau setidaknya mereka menyembunyikan suatu masalah.

Mulailah dengan menghapus semua abstraksi Anda, sebagai gudangnya. Suntikkan DbContext sebagai titik awal:

protected readonly AppDbContext _context = null;

public NutrientService(AppDbContext context)
{
    _context = context ?? throw new ArgumentNullException("context");
}

public IList<ProductNutrient> GetNutrients()
{
    var productNutrients = context.ProductNutrients
        .ToList();

    return productNutrients;
}

Apakah ini mengembalikan data lengkap atau nilai kosong? Jika masih kosong maka Anda perlu memeriksa string koneksi yang digunakan saat runtime karena mungkin menunjuk pada instance database yang lebih lama dari yang Anda lihat sekarang. Ini tampaknya menjadi masalah yang cukup umum ketika orang menggunakan SSMS atau desainer untuk meninjau skema DB, tapi kemudian runtime web/app.config menunjuk ke lokasi DB yang lebih lama atau bersama, atau DB yang dihasilkan yang memiliki beberapa data , tapi bukan apa yang Anda harapkan.

Jika ia mengembalikan data yang Anda harapkan, maka abstraksi Anda (Repositori) memiliki cacat dalam beberapa hal. Pertanyaan pertama adalah Mengapa Anda mengimplementasikan Repositori di sekitar DbContext? Saran saya mengenai repositori adalah Generic Repositories, I.e. Repository<ProductNutrient> adalah anti-pola yang sangat buruk. Jika Anda mengimplementasikan Repositori karena Anda menemukan contohnya, Anda perlu memahami alasan yang mendasarinya. Jika Anda menerapkan Repositori untuk menyembunyikan fakta bahwa Anda menggunakan EntityFramework atau menyembunyikan DbContext, IMHO ini adalah alasan yang salah untuk mengimplementasikan Repositori. Satu-satunya alasan untuk mempertimbangkan penerapan pola Repositori melalui EntityFramework adalah untuk membuat kode Anda lebih mudah untuk diuji unit. Dalam melakukan hal itu saya sangat menyarankan untuk memanfaatkan IQueryable<TEntity> sebagai tipe pengembalian. Mungkin saja .Table mengembalikan IQueryable<ProductNutrient>, tetapi jika mengembalikan DbSet<ProductNutrient> maka Anda sebaiknya menggunakan DbContext saja. Jika ia mengembalikan sesuatu seperti IEnumerable<ProductNutrient> maka Anda berpotensi membiarkan sistem Anda terbuka terhadap batasan kinerja yang signifikan karena Anda kehilangan sebagian besar kemampuan yang dapat diberikan EF.

Jika Anda tidak berencana menggunakan pengujian unit di mana Anda perlu meniru lapisan data Anda sehingga pengujian mendapatkan status yang diketahui dan dapat diandalkan, maka sebenarnya tidak ada pembenaran untuk membuat kelas Repositori dan berpotensi menerapkan batasan yang sangat mahal pada akses data Anda. Saya menguraikan masalah dengan pola Repositori Generik dan EF dalam jawaban saya atas pertanyaan ini: (Bagaimana cara mengatur beberapa layanan dari Entity Framework Core pada Pola Repositori?) Anda dapat sepenuhnya menguji kode yang menggunakan DbContext menggunakan gambar database pengujian integrasi khusus, atau database dalam memori, atau dengan sedikit lebih banyak pekerjaan, mengejek DbContext/DbSets. Untuk pengujian unit yang dijalankan berulang kali selama pengembangan sebelum integrasi, meniru kelas Repositori jauh lebih sederhana.

person Steve Py    schedule 06.01.2021
comment
Terima kasih atas bantuan Anda, melihat melalui DBContext memecahkan masalah. Beralih dari model Repo tidaklah sepadan, saya sedang mengerjakan kerangka kerja OpenSource yang memanfaatkannya, dan menghabiskan waktu untuk mengubah semua itu tidak akan memberikan nilai signifikan untuk menjamin perubahannya. - person DanCRichards; 08.01.2021