C# 将实体框架T4模板与系统版本的时态表一起使用

C# 将实体框架T4模板与系统版本的时态表一起使用,c#,sql-server,entity-framework,t4,temporal-tables,C#,Sql Server,Entity Framework,T4,Temporal Tables,为了解决我的错误(如下所示),我想知道如何编辑我的Entity Framework T4模板,以便它将“HasDatabaseGenerateOption(DatabaseGenerateOption.Computed)”添加到自动生成类的POCO配置部分中我的时态表生成的始终作为行开始/结束列中,如下所示: Property(x => x.ValidFrom).HasColumnName(@"valid_from").HasColumnType("datetime2").IsRequir

为了解决我的错误(如下所示),我想知道如何编辑我的Entity Framework T4模板,以便它将“HasDatabaseGenerateOption(DatabaseGenerateOption.Computed)”添加到自动生成类的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);
我可以手动添加它(这解决了我的错误),但当我保存T4模板时,它当然会被覆盖

尝试插入记录时出错: 无法将显式值插入表“my_table”中生成的ALWAYS列中。请将insert与列列表一起使用以排除生成的ALWAYS列,或将默认值插入生成的ALWAYS列中

我看到了这篇文章,但它没有帮助(可能它只在使用edmx文件时有效,或者我不了解解决方案):

我的时态表示例

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();

我想出来了。我不得不编辑EF.Reverse.POCO.Core.ttinclude文件,将“IsGeneratedAlwaysType”添加到许多类、方法和SQL查询中。我基本上在我找到的“IsForeignKey”的任何地方都添加了它。我已将添加到每个部分的片段粘贴到下面

public class Column
{
    public bool IsGeneratedAlwaysType;









我找到了一份工作;这不是我想要添加到T4模板中的内容,但它解决了错误。在T4模板中,我编辑了以下行:Settings.ColumnFilterExclude=null;to Settings.ColumnFilterExclude=新的正则表达式(“^valid\u从$| ^valid\u到$”;此解决方案之所以有效,是因为我的上下文中名为“valid_from”和“valid_to”的任何其他表中没有任何其他列。如果我这样做了,并且想在我的上下文中包含它们,我就不能这样做,因为这也会排除它们。这有帮助吗?它解释了如何通过使用“buddy”类向模型中添加注释而不被覆盖Hanks,我没有使用链接中的解决方案所使用的.edmx文件,但如果我能首先弄清楚如何让T4模板在从数据库生成部分类时创建它们,它可能会对我有所帮助。不过,它并不像我所寻找的解决方案那样简洁。
    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