Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Kerangka Entitas tidak berfungsi dengan tabel temporal

Ada dua solusi untuk masalah ini:

  1. Di jendela properti untuk kolom di desainer EDMX, ubah StoreGeneratedPattern pada PERIOD kolom (ValidFrom dan ValidTo dalam kasus saya) menjadi identity . Identitas lebih baik daripada yang dihitung karena dihitung akan menyebabkan EF me-refresh nilai pada Sisipan dan Pembaruan sebagai lawan hanya sisipan dengan identity
  2. Buat IDbCommandTreeInterceptor implementasi untuk menghapus kolom periode. Ini adalah solusi pilihan saya karena tidak memerlukan pekerjaan tambahan saat menambahkan tabel baru ke model.

Inilah implementasi saya:

using System.Data.Entity.Infrastructure.Interception; 
using System.Data.Entity.Core.Common.CommandTrees; 
using System.Data.Entity.Core.Metadata.Edm; 
using System.Collections.ObjectModel;

internal class TemporalTableCommandTreeInterceptor : IDbCommandTreeInterceptor
{
    private static readonly List<string> _namesToIgnore = new List<string> { "ValidFrom", "ValidTo" };

    public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
    {
        if (interceptionContext.OriginalResult.DataSpace == DataSpace.SSpace)
        {
            var insertCommand = interceptionContext.Result as DbInsertCommandTree;
            if (insertCommand != null)
            {
                var newSetClauses = GenerateSetClauses(insertCommand.SetClauses);

                var newCommand = new DbInsertCommandTree(
                    insertCommand.MetadataWorkspace,
                    insertCommand.DataSpace,
                    insertCommand.Target,
                    newSetClauses,
                    insertCommand.Returning);

                interceptionContext.Result = newCommand;
            }

            var updateCommand = interceptionContext.Result as DbUpdateCommandTree;
            if (updateCommand != null)
            {
                var newSetClauses = GenerateSetClauses(updateCommand.SetClauses);

                var newCommand = new DbUpdateCommandTree(
                    updateCommand.MetadataWorkspace,
                    updateCommand.DataSpace,
                    updateCommand.Target,
                    updateCommand.Predicate,
                    newSetClauses,
                    updateCommand.Returning);

                interceptionContext.Result = newCommand;
            }
        }
    }

    private static ReadOnlyCollection<DbModificationClause> GenerateSetClauses(IList<DbModificationClause> modificationClauses)
    {
        var props = new List<DbModificationClause>(modificationClauses);
        props = props.Where(_ => !_namesToIgnore.Contains((((_ as DbSetClause)?.Property as DbPropertyExpression)?.Property as EdmProperty)?.Name)).ToList();

        var newSetClauses = new ReadOnlyCollection<DbModificationClause>(props);
        return newSetClauses;
    }
}

Daftarkan pencegat ini dengan EF dengan menjalankan kode berikut di mana saja dalam kode Anda sebelum Anda menggunakan konteks Anda:

DbInterception.Add(new TemporalTableCommandTreeInterceptor());


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. "Permintaan tidak diizinkan di Waitfor" Kesalahan 101 di SQL Server

  2. Cara Memodifikasi Periode Retensi Change Data Capture (CDC) di SQL Server - Tutorial SQL Server

  3. mengonversi stempel waktu Epoch ke server sql (format yang dapat dibaca manusia)

  4. 5 Cara Mendapatkan Nama Bulan Pendek dari Tanggal di SQL Server

  5. Belajar Menyimpan dan Menganalisis Dokumen di Sistem File Windows dengan Pencarian Semantik SQL Server – Bagian 1