Использование шаблонов Entity Framework T4 с системными темпоральными временными таблицами - PullRequest
0 голосов
/ 22 мая 2018

Чтобы устранить мою ошибку (показанную ниже), я хотел бы знать, как отредактировать мой шаблон Entity Framework T4 так, чтобы он добавлял « HasDatabaseGeneratedOption (DatabaseGeneratedOption.Computed) » в GENERATED ВСЕГДА КАК НАЧАТЬ СТАРТ /Столбцы END моей временной таблицы в разделе «Конфигурация POCO» автоматически сгенерированного класса выглядят так:

Property(x => x.ValidFrom).HasColumnName(@"valid_from").HasColumnType("datetime2").IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);
Property(x => x.ValidTo).HasColumnName(@"valid_to").HasColumnType("datetime2").IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);

Я могу добавить это вручную (что устраняет мою ошибку), но, конечно, оно перезаписывается при сохраненииШаблон Т4.

Ошибка при попытке вставить запись : "Невозможно вставить явное значение в столбец GENERATED ALWAYS в таблице" my_table ". Используйте INSERT со списком столбцов, чтобы исключить столбец GENERATED ALWAYS, иливставьте DEFAULT в столбец GENERATED ВСЕГДА. "

Я видел этот пост, но он не помог (возможно, он работает только при использовании файлов edmx, или я не понял решения): EntityFramework не работает с временной таблицей

Пример моей временной таблицы :

CREATE TABLE [dbo].[my_table](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [user_id] [int] NOT NULL,
    [valid_from] [datetime2](7) GENERATED ALWAYS AS ROW START NOT NULL,
    [valid_to] [datetime2](7) GENERATED ALWAYS AS ROW END NOT NULL,
 CONSTRAINT [PK_my_table] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
    PERIOD FOR SYSTEM_TIME ([valid_from], [valid_to])
) ON [PRIMARY]
WITH
(
SYSTEM_VERSIONING = ON ( HISTORY_TABLE = [dbo].[my_table_history] )
)
GO
ALTER TABLE [dbo].[my_table] ADD  CONSTRAINT [DF_my_table_SysStart]  DEFAULT (sysutcdatetime()) FOR [valid_from]
GO
ALTER TABLE [dbo].[my_table] ADD  CONSTRAINT [DF_my_table_SysEnd]  DEFAULT (CONVERT([datetime2](7),'9999-12-31 23:59:59')) FOR [valid_to]
GO

Пример кода для вставки записи :

var recordToCreate = new MyTable()
{
    UserId = info.UserId,
    ValidFrom = info.ValidFrom,
    ValidTo = info.ValidTo,
};
_context.MyTables.Add(recordToCreate);
_context.SaveChanges();

1 Ответ

0 голосов
/ 23 мая 2018

Я понял это.Мне пришлось отредактировать файл EF.Reverse.POCO.Core.ttinclude, добавив IsGeneratedAlwaysType к ряду классов, методов и SQL-запросов.Я в основном добавил его везде, где нашел 'IsForeignKey'.Я вставил ниже фрагмент того, что я добавил в каждый раздел.

public class Column
{
    public bool IsGeneratedAlwaysType;

    private void SetupConfig()
    {
        else if (IsGeneratedAlwaysType)
        {
            if(Settings.UseDataAnnotations)
                DataAnnotations.Add("DatabaseGenerated(DatabaseGeneratedOption.Computed)");
            else
                databaseGeneratedOption = string.Format(".HasDatabaseGeneratedOption({0}DatabaseGeneratedOption.Computed)", schemaReference);
        }

    private static Column CreateColumn(IDataRecord rdr, Regex rxClean, Table table, Regex columnFilterExclude)
    { 
        var col = new Column
        {
            IsGeneratedAlwaysType = rdr["IsGeneratedAlwaysType"].ToString().Trim().ToLower() == "true",

private class SqlServerSchemaReader : SchemaReader
{
    private const string TableSQL = @"
    CAST(CASE WHEN COLUMNPROPERTY(OBJECT_ID(QUOTENAME(c.TABLE_SCHEMA) + '.' + QUOTENAME(c.TABLE_NAME)), c.COLUMN_NAME, 'GeneratedAlwaysType') > 0 THEN 1
         ELSE 0
       END AS BIT) AS IsGeneratedAlwaysType
    FROM    #Columns c

private const string SynonymTableSQLSetup = @"
        CAST(CASE WHEN COLUMNPROPERTY(OBJECT_ID(QUOTENAME(sc.NAME) + '.' + QUOTENAME(o.NAME)), c.NAME, 'GeneratedAlwaysType') > 0 THEN 1
                  ELSE 0
             END AS BIT) AS IsGeneratedAlwaysType
        INTO    #SynonymDetails
        FROM    sys.synonyms sn

INSERT INTO #SynonymDetails (SchemaName, TableName, TableType, Ordinal, ColumnName, IsNullable, TypeName, [MaxLength], [Precision],
                            [Default], DateTimePrecision, Scale, IsIdentity, IsStoreGenerated, PrimaryKey, PrimaryKeyOrdinal, IsForeignKey, IsGeneratedAlwaysType)

CAST(CASE WHEN COLUMNPROPERTY(st.base_object_id, c.NAME, ''GeneratedAlwaysType'') > 0 THEN 1
                ELSE 0
            END AS BIT) AS IsGeneratedAlwaysType
FROM    #SynonymTargets st
    INNER JOIN sys.columns c

        private const string SynonymTableSQL = @"
SELECT SchemaName, TableName, TableType, Ordinal, ColumnName, IsNullable, TypeName, [MaxLength], [Precision],
    [Default], DateTimePrecision, Scale, IsIdentity, IsStoreGenerated, PrimaryKey, PrimaryKeyOrdinal, IsForeignKey, IsGeneratedAlwaysType FROM #SynonymDetails";

        private const string TableSQLCE = @"
0 as IsGeneratedAlwaysType
FROM    INFORMATION_SCHEMA.COLUMNS c
...