Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Khung thực thể không hoạt động với bảng tạm thời

Có hai giải pháp cho vấn đề này:

  1. Trong cửa sổ thuộc tính cho cột trong trình thiết kế EDMX, hãy thay đổi StoreGeneratedPattern trên PERIOD cột (ValidFrom và ValidTo trong trường hợp của tôi) là identity . Danh tính tốt hơn được tính toán vì được tính toán sẽ khiến EF làm mới các giá trị trên một Chèn và Cập nhật thay vì chỉ một chèn có identity
  2. Tạo IDbCommandTreeInterceptor thực hiện để loại bỏ các cột thời kỳ. Đây là giải pháp ưa thích của tôi vì nó không yêu cầu phải thực hiện thêm khi thêm các bảng mới vào mô hình.

Đây là cách triển khai của tôi:

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;
    }
}

Đăng ký bộ chặn này với EF bằng cách chạy phần sau ở bất kỳ đâu trong mã của bạn trước khi bạn sử dụng ngữ cảnh của mình:

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. Tại sao không có hàm cửa sổ trong mệnh đề where?

  2. SQL Server - dừng hoặc ngắt việc thực thi tập lệnh SQL

  3. Chuyển đổi ‘smalldatetime’ thành ‘datetime’ trong SQL Server (Ví dụ T-SQL)

  4. 2 cách để xem liệu các tính năng không dùng nữa có còn được sử dụng trong phiên bản máy chủ SQL hay không

  5. Mã hóa ký tự mặc định của SQL Server