|
3649 | 3649 | UseLazyLoadingProxies = Settings.UseLazyLoading && Settings.IsEfCore3Plus(), |
3650 | 3650 | SqlParameter = Settings.SqlParameter(), |
3651 | 3651 | Triggers = _tables.Where(x => !string.IsNullOrEmpty(x.Table.TriggerName)) |
3652 | | - .Select(x => new Trigger { TableName = x.Table.NameHumanCase, TriggerName = x.Table.TriggerName }).ToList() |
| 3652 | + .Select(x => new Trigger { TableName = x.Table.NameHumanCase, TriggerName = x.Table.TriggerName }).ToList(), |
| 3653 | + MemoryOptimisedTables = _tables.Where(x => x.Table.IsMemoryOptimised).Select(x => x.Table.NameHumanCase).ToList() |
3653 | 3654 | }; |
3654 | 3655 |
|
3655 | | - data.hasIndexes = data.indexes.Any(); |
3656 | | - data.hasTriggers = data.Triggers.Any(); |
3657 | | - data.hasSequences = data.Sequences.Any(); |
| 3656 | + data.hasIndexes = data.indexes.Any(); |
| 3657 | + data.hasTriggers = data.Triggers.Any(); |
| 3658 | + data.hasSequences = data.Sequences.Any(); |
| 3659 | + data.hasMemoryOptimisedTables = data.MemoryOptimisedTables.Any(); |
3658 | 3660 |
|
3659 | 3661 | var co = new CodeOutput(string.Empty, filename, "Database context", Settings.ContextFolder, _globalUsings); |
3660 | 3662 | co.AddUsings(_template.DatabaseContextUsings(data)); |
|
4355 | 4357 | AddIndexesToFilters(rawIndexes); |
4356 | 4358 | SetPrimaryKeys(); |
4357 | 4359 | AddForeignKeysToFilters(rawForeignKeys); |
| 4360 | + |
| 4361 | + if (Settings.IsEfCore6Plus()) |
| 4362 | + { |
| 4363 | + var rawMemoryOptimisedTables = DatabaseReader.ReadMemoryOptimisedTables(); |
| 4364 | + AddMemoryOptimisedTablesToFilters(rawMemoryOptimisedTables); |
| 4365 | + } |
4358 | 4366 |
|
4359 | 4367 | if (Settings.IsEfCore7Plus()) |
4360 | 4368 | { |
|
4718 | 4726 | } |
4719 | 4727 | } |
4720 | 4728 |
|
| 4729 | + private void AddMemoryOptimisedTablesToFilters(List<RawMemoryOptimisedTable> memoryOptimisedTables) |
| 4730 | + { |
| 4731 | + if (memoryOptimisedTables == null || !memoryOptimisedTables.Any()) |
| 4732 | + return; |
| 4733 | + |
| 4734 | + foreach (var filterKeyValuePair in FilterList.GetFilters()) |
| 4735 | + { |
| 4736 | + var filter = filterKeyValuePair.Value; |
| 4737 | + |
| 4738 | + Table t = null; |
| 4739 | + foreach (var trigger in memoryOptimisedTables) |
| 4740 | + { |
| 4741 | + // Lookup table |
| 4742 | + if (t == null || t.DbName != trigger.TableName || t.Schema.DbName != trigger.SchemaName) |
| 4743 | + t = filter.Tables.GetTable(trigger.TableName, trigger.SchemaName); |
| 4744 | + |
| 4745 | + if (t == null) |
| 4746 | + continue; |
| 4747 | + |
| 4748 | + t.IsMemoryOptimised = true; |
| 4749 | + } |
| 4750 | + } |
| 4751 | + } |
| 4752 | + |
4721 | 4753 | private void AddExtendedPropertiesToFilters(List<RawExtendedProperty> extendedProperties) |
4722 | 4754 | { |
4723 | 4755 | if (extendedProperties == null || !extendedProperties.Any()) |
@@ -12215,6 +12247,16 @@ and limitations under the License. |
12215 | 12247 | protected abstract string EnumSQL(string table, string nameField, string valueField); |
12216 | 12248 | protected abstract string SequenceSQL(); |
12217 | 12249 | protected abstract string TriggerSQL(); |
| 12250 | + protected abstract string[] MemoryOptimisedSQL(); |
| 12251 | + |
| 12252 | + protected enum MemoryOptimised |
| 12253 | + { |
| 12254 | + CompatibilityLevel, |
| 12255 | + InMemorySupported, |
| 12256 | + TableList, |
| 12257 | + |
| 12258 | + Count // This is always the last value |
| 12259 | + } |
12218 | 12260 |
|
12219 | 12261 | // Synonym |
12220 | 12262 | protected abstract string SynonymTableSQLSetup(); |
@@ -13112,6 +13154,62 @@ and limitations under the License. |
13112 | 13154 | return result; |
13113 | 13155 | } |
13114 | 13156 |
|
| 13157 | + public List<RawMemoryOptimisedTable> ReadMemoryOptimisedTables() |
| 13158 | + { |
| 13159 | + if (DatabaseReaderPlugin != null) |
| 13160 | + return DatabaseReaderPlugin.ReadMemoryOptimisedTables(); |
| 13161 | + |
| 13162 | + var result = new List<RawMemoryOptimisedTable>(); |
| 13163 | + try |
| 13164 | + { |
| 13165 | + using (var conn = _factory.CreateConnection()) |
| 13166 | + { |
| 13167 | + if (conn == null) |
| 13168 | + return result; |
| 13169 | + |
| 13170 | + conn.ConnectionString = Settings.ConnectionString; |
| 13171 | + conn.Open(); |
| 13172 | + |
| 13173 | + var cmd = GetCmd(conn); |
| 13174 | + if (cmd == null) |
| 13175 | + return result; |
| 13176 | + |
| 13177 | + var sql = MemoryOptimisedSQL(); |
| 13178 | + if (sql == null || sql.Length != (int) MemoryOptimised.Count) |
| 13179 | + return result; |
| 13180 | + |
| 13181 | + cmd.CommandText = sql[(int) MemoryOptimised.CompatibilityLevel]; |
| 13182 | + var compatibilityLevel = Convert.ToInt16(cmd.ExecuteScalar()); |
| 13183 | + if(compatibilityLevel < 130) |
| 13184 | + return result; |
| 13185 | + |
| 13186 | + cmd.CommandText = sql[(int) MemoryOptimised.InMemorySupported]; |
| 13187 | + var inMemorySupported = Convert.ToBoolean(cmd.ExecuteScalar()); |
| 13188 | + if(!inMemorySupported) |
| 13189 | + return result; |
| 13190 | + |
| 13191 | + cmd.CommandText = sql[(int) MemoryOptimised.TableList]; |
| 13192 | + using (var rdr = cmd.ExecuteReader()) |
| 13193 | + { |
| 13194 | + while (rdr.Read()) |
| 13195 | + { |
| 13196 | + var index = new RawMemoryOptimisedTable |
| 13197 | + ( |
| 13198 | + rdr["SchemaName"].ToString().Trim(), |
| 13199 | + rdr["TableName"].ToString().Trim() |
| 13200 | + ); |
| 13201 | + result.Add(index); |
| 13202 | + } |
| 13203 | + } |
| 13204 | + } |
| 13205 | + } |
| 13206 | + catch (Exception) |
| 13207 | + { |
| 13208 | + // Memory optimised tables are not supported |
| 13209 | + } |
| 13210 | + return result; |
| 13211 | + } |
| 13212 | + |
13115 | 13213 | private static string GetReaderString(DbDataReader rdr, string name) |
13116 | 13214 | { |
13117 | 13215 | try |
@@ -13311,13 +13409,14 @@ and limitations under the License. |
13311 | 13409 |
|
13312 | 13410 | public interface IDatabaseReaderPlugin |
13313 | 13411 | { |
13314 | | - List<RawTable> ReadTables(); |
13315 | | - List<RawForeignKey> ReadForeignKeys(); |
13316 | | - List<RawIndex> ReadIndexes(); |
13317 | | - List<RawExtendedProperty> ReadExtendedProperties(); |
13318 | | - List<RawStoredProcedure> ReadStoredProcs(); |
13319 | | - List<RawSequence> ReadSequences(); |
13320 | | - List<RawTrigger> ReadTriggers(); |
| 13412 | + List<RawTable> ReadTables(); |
| 13413 | + List<RawForeignKey> ReadForeignKeys(); |
| 13414 | + List<RawIndex> ReadIndexes(); |
| 13415 | + List<RawExtendedProperty> ReadExtendedProperties(); |
| 13416 | + List<RawStoredProcedure> ReadStoredProcs(); |
| 13417 | + List<RawSequence> ReadSequences(); |
| 13418 | + List<RawTrigger> ReadTriggers(); |
| 13419 | + List<RawMemoryOptimisedTable> ReadMemoryOptimisedTables(); |
13321 | 13420 |
|
13322 | 13421 | IDatabaseToPropertyType GetDatabaseToPropertyTypeMapping(); |
13323 | 13422 | } |
@@ -13439,6 +13538,11 @@ and limitations under the License. |
13439 | 13538 | return string.Empty; |
13440 | 13539 | } |
13441 | 13540 |
|
| 13541 | + protected override string[] MemoryOptimisedSQL() |
| 13542 | + { |
| 13543 | + return null; |
| 13544 | + } |
| 13545 | + |
13442 | 13546 | protected override string SynonymTableSQLSetup() |
13443 | 13547 | { |
13444 | 13548 | return string.Empty; |
@@ -13562,6 +13666,11 @@ and limitations under the License. |
13562 | 13666 | return string.Empty; |
13563 | 13667 | } |
13564 | 13668 |
|
| 13669 | + protected override string[] MemoryOptimisedSQL() |
| 13670 | + { |
| 13671 | + return null; |
| 13672 | + } |
| 13673 | + |
13565 | 13674 | protected override string SynonymTableSQLSetup() |
13566 | 13675 | { |
13567 | 13676 | return string.Empty; |
@@ -13703,6 +13812,11 @@ and limitations under the License. |
13703 | 13812 | return string.Empty; |
13704 | 13813 | } |
13705 | 13814 |
|
| 13815 | + protected override string[] MemoryOptimisedSQL() |
| 13816 | + { |
| 13817 | + return null; |
| 13818 | + } |
| 13819 | + |
13706 | 13820 | protected override string SynonymTableSQLSetup() |
13707 | 13821 | { |
13708 | 13822 | return string.Empty; |
@@ -13959,6 +14073,11 @@ FROM INFORMATION_SCHEMA.triggers |
13959 | 14073 | ORDER BY SchemaName, TableName, TriggerName;"; |
13960 | 14074 | } |
13961 | 14075 |
|
| 14076 | + protected override string[] MemoryOptimisedSQL() |
| 14077 | + { |
| 14078 | + return null; |
| 14079 | + } |
| 14080 | + |
13962 | 14081 | protected override string SynonymTableSQLSetup() |
13963 | 14082 | { |
13964 | 14083 | return string.Empty; |
@@ -14207,6 +14326,17 @@ ORDER BY SchemaName, TableName, TriggerName;"; |
14207 | 14326 | IsUniqueConstraint ? "true" : "false", IsClustered ? "true" : "false"); |
14208 | 14327 | } |
14209 | 14328 | } |
| 14329 | + public class RawMemoryOptimisedTable |
| 14330 | + { |
| 14331 | + public readonly string SchemaName; |
| 14332 | + public readonly string TableName; |
| 14333 | + |
| 14334 | + public RawMemoryOptimisedTable(string schemaName, string tableName) |
| 14335 | + { |
| 14336 | + SchemaName = schemaName; |
| 14337 | + TableName = tableName; |
| 14338 | + } |
| 14339 | + } |
14210 | 14340 |
|
14211 | 14341 | public class RawSequence |
14212 | 14342 | { |
@@ -14521,6 +14651,11 @@ SELECT * FROM MultiContext.ForeignKey;"; |
14521 | 14651 | return string.Empty; |
14522 | 14652 | } |
14523 | 14653 |
|
| 14654 | + protected override string[] MemoryOptimisedSQL() |
| 14655 | + { |
| 14656 | + return null; |
| 14657 | + } |
| 14658 | + |
14524 | 14659 | protected override string SynonymTableSQLSetup() |
14525 | 14660 | { |
14526 | 14661 | return string.Empty; |
@@ -15065,6 +15200,16 @@ WHERE T.type = 'TR' |
15065 | 15200 | ORDER BY SchemaName, TableName, TriggerName;"; |
15066 | 15201 | } |
15067 | 15202 |
|
| 15203 | + protected override string[] MemoryOptimisedSQL() |
| 15204 | + { |
| 15205 | + return new string[] |
| 15206 | + { |
| 15207 | + "SELECT compatibility_level FROM sys.databases WHERE name = DB_NAME();", |
| 15208 | + "SELECT CAST(SERVERPROPERTY(N'IsXTPSupported') AS BIT) AS IsXTPSupported;", |
| 15209 | + "SELECT SCHEMA_NAME(schema_id) SchemaName, name TableName FROM sys.tables WHERE is_memory_optimized = 1;" |
| 15210 | + }; |
| 15211 | + } |
| 15212 | + |
15068 | 15213 | protected override string SynonymTableSQLSetup() |
15069 | 15214 | { |
15070 | 15215 | return @" |
@@ -16145,12 +16290,14 @@ SELECT SERVERPROPERTY('Edition') AS Edition, |
16145 | 16290 | public bool UsesDictionary; |
16146 | 16291 | public bool HasPrimaryKey; |
16147 | 16292 | public bool RemoveTable; |
| 16293 | + public bool IsMemoryOptimised; |
16148 | 16294 | public string AdditionalComment; |
16149 | 16295 | public string PluralNameOverride; |
16150 | 16296 | public string DbSetModifier = "public"; |
16151 | 16297 | public string BaseClasses; |
16152 | 16298 | public string TriggerName; |
16153 | 16299 |
|
| 16300 | + |
16154 | 16301 | public List<Column> Columns; |
16155 | 16302 | public List<PropertyAndComments> ReverseNavigationProperty; |
16156 | 16303 | public List<string> MappingConfiguration; |
@@ -16575,6 +16722,8 @@ SELECT SERVERPROPERTY('Edition') AS Edition, |
16575 | 16722 | public bool UseLazyLoadingProxies { get; set; } |
16576 | 16723 | public bool hasTriggers { get; set; } |
16577 | 16724 | public List<Trigger> Triggers { get; set; } |
| 16725 | + public bool hasMemoryOptimisedTables { get; set; } |
| 16726 | + public List<string> MemoryOptimisedTables { get; set; } |
16578 | 16727 | } |
16579 | 16728 | public class FactoryModel |
16580 | 16729 | { |
@@ -23075,6 +23224,13 @@ using {{this}};{{#newline}} |
23075 | 23224 | {{/each}} |
23076 | 23225 | {{/if}} |
23077 | 23226 |
|
| 23227 | +{{#if hasMemoryOptimisedTables}} |
| 23228 | +{{#newline}} |
| 23229 | +{{#each MemoryOptimisedTables}} |
| 23230 | + modelBuilder.Entity<{{this}}>().IsMemoryOptimized();{{#newline}} |
| 23231 | +{{/each}} |
| 23232 | +{{/if}} |
| 23233 | + |
23078 | 23234 | {{#if hasStoredProcs}} |
23079 | 23235 | {{#newline}} |
23080 | 23236 | {{#each storedProcs}} |
@@ -24694,6 +24850,13 @@ using {{this}};{{#newline}} |
24694 | 24850 | {{/each}} |
24695 | 24851 | {{/if}} |
24696 | 24852 |
|
| 24853 | +{{#if hasMemoryOptimisedTables}} |
| 24854 | +{{#newline}} |
| 24855 | +{{#each MemoryOptimisedTables}} |
| 24856 | + modelBuilder.Entity<{{this}}>().IsMemoryOptimized();{{#newline}} |
| 24857 | +{{/each}} |
| 24858 | +{{/if}} |
| 24859 | + |
24697 | 24860 | {{#if hasTriggers}} |
24698 | 24861 | {{#newline}} |
24699 | 24862 | {{#each Triggers}} |
|
0 commit comments