From bce7cd964234077c3b55162d16e714ab7a110cd4 Mon Sep 17 00:00:00 2001 From: Andriy Svyryd Date: Fri, 29 Oct 2021 10:22:37 -0700 Subject: [PATCH] Add documentation for pre-convention model configuration Part of #3278 Fixes #571 --- entity-framework/core/cli/powershell.md | 4 +- .../core/modeling/bulk-configuration.md | 71 +++++++++++++++++++ .../core/modeling/conventions.md.stub | 0 .../providers/cosmos/unstructured-data.md | 2 +- entity-framework/toc.yml | 7 +- .../BulkConfiguration.csproj | 14 ++++ .../Modeling/BulkConfiguration/Currency.cs | 15 ++++ .../BulkConfiguration/CurrencyConverter.cs | 16 +++++ .../BulkConfiguration/MetadataAPIContext.cs | 33 +++++++++ .../BulkConfiguration/PreConventionContext.cs | 44 ++++++++++++ .../Modeling/BulkConfiguration/Product.cs | 8 +++ .../Modeling/BulkConfiguration/Program.cs | 51 +++++++++++++ samples/core/Samples.sln | 65 +++++++++-------- 13 files changed, 295 insertions(+), 35 deletions(-) create mode 100644 entity-framework/core/modeling/bulk-configuration.md delete mode 100644 entity-framework/core/modeling/conventions.md.stub create mode 100644 samples/core/Modeling/BulkConfiguration/BulkConfiguration.csproj create mode 100644 samples/core/Modeling/BulkConfiguration/Currency.cs create mode 100644 samples/core/Modeling/BulkConfiguration/CurrencyConverter.cs create mode 100644 samples/core/Modeling/BulkConfiguration/MetadataAPIContext.cs create mode 100644 samples/core/Modeling/BulkConfiguration/PreConventionContext.cs create mode 100644 samples/core/Modeling/BulkConfiguration/Product.cs create mode 100644 samples/core/Modeling/BulkConfiguration/Program.cs diff --git a/entity-framework/core/cli/powershell.md b/entity-framework/core/cli/powershell.md index 1d08afdd08..a2feef5969 100644 --- a/entity-framework/core/cli/powershell.md +++ b/entity-framework/core/cli/powershell.md @@ -185,13 +185,13 @@ Parameters: The [common parameters](#common-parameters) are listed above. -Example that uses the defaults and works if there is only one `DbContext` in the project: +The following example uses the defaults and works if there is only one `DbContext` in the project: ```powershell Optimize-DbContext ``` -Example that optimizes the model for the context with the specified name amd places it in a separate folder and namespace: +The following example optimizes the model for the context with the specified name and places it in a separate folder and namespace: ```powershell Optimize-DbContext -OutputDir Models -Namespace BlogModels -Context BlogContext diff --git a/entity-framework/core/modeling/bulk-configuration.md b/entity-framework/core/modeling/bulk-configuration.md new file mode 100644 index 0000000000..e7e5332a28 --- /dev/null +++ b/entity-framework/core/modeling/bulk-configuration.md @@ -0,0 +1,71 @@ +--- +title: Model Bulk Configuration - EF Core +description: How to apply bulk configuration during model building in Entity Framework Core +author: AndriySvyryd +ms.date: 11/05/2021 +uid: core/modeling/bulk-configuration +--- +# Model bulk configuration + +When an aspect needs to be configured in the same way across multiple entity types, the following techniques allow to reduce code duplication and consolidate the logic. + +See the [full sample project](https://github.com/dotnet/EntityFramework.Docs/tree/main/samples/core/Modeling/BulkConfiguration) containing the code snippets presented below. + +## Bulk configuration in OnModelCreating + +Every builder object returned from exposes a or `Metadata` property that provides a low-level access to the objects that comprise the model. In particular, there are methods that allow you to iterate over specific objects in the model and apply common configuration to them. + +In the following example the model contains a custom value type `Currency`: + +[!code-csharp[Main](../../../samples/core/Modeling/BulkConfiguration/Currency.cs?name=Currency)] + +Properties of this type are not discovered by default as the current EF provider doesn't know how to map it to a database type. This snippet of `OnModelCreating` adds all properties of the type `Currency` and configures a value converter to a supported type - `decimal`: + +[!code-csharp[Main](../../../samples/core/Modeling/BulkConfiguration/MetadataAPIContext.cs?name=MetadataAPI)] + +[!code-csharp[Main](../../../samples/core/Modeling/BulkConfiguration/CurrencyConverter.cs?name=CurrencyConverter)] + +### Drawbacks of the Metadata API + +- Unlike Fluent API, every modification to the model needs to be done explicitly. For example, if some of the `Currency` properties were configured as navigations by a convention then you need to first remove the navigation referencing the CLR property before adding an entity type property for it. [#9117](https://github.com/dotnet/efcore/issues/9117) will improve this. +- The conventions run after each change. If you remove a navigation discovered by a convention then the convention will run again and could add it back. To prevent this from happening you would need to either delay the conventions until after the property is added by calling and later disposing the returned object or to mark the CLR property as ignored using . +- Entity types might be added after this iteration happens and the configuration won't be applied to them. This can usually be prevented by placing this code at the end of `OnModelCreating`, but if you have two interdependent sets of configurations there might not be an order that will allow them to be applied consistently. + +## Pre-convention configuration + +EF Core 6.0 allows the mapping configuration to be specified once for a given CLR type; that configuration is then applied to all properties of that type in the model as they are discovered. This is called "pre-convention model configuration", since it configures aspects of the model that are then used by the model building conventions. Such configuration is applied by overriding `` on the type derived from ``. + +This example shows how configure all properties of type `Currency` to have a value converter: + +[!code-csharp[Main](../../../samples/core/Modeling/BulkConfiguration/PreConventionContext.cs?name=CurrencyConversion)] + +And this example shows how to configure some facets on properties of type `string`: + +[!code-csharp[Main](../../../samples/core/Modeling/BulkConfiguration/PreConventionContext.cs?name=StringFacets)] + +> [!NOTE] +> The type specified in a call from `ConfigureConventions` can be a base type, an interface or a generic type definition. All matching configurations will be applied in order from the least specific: +> +> 1. Interface +> 2. Base type +> 3. Generic type definition +> 4. Non-nullable value type +> 5. Exact type + +### Ignoring types + +Pre-convention configuration also allows to ignore a type and prevent it from being discovered by conventions either as an entity type or as a property on an entity type: + +[!code-csharp[Main](../../../samples/core/Modeling/BulkConfiguration/PreConventionContext.cs?name=IgnoreInterface)] + +### Default type mapping + +Generally, EF is able to translate queries with constants of a type that is not supported by the provider, as long as you have specified a value converter for a property of this type. However, in queries that don't involve any properties of this type, there is no way for EF to find the correct value converter. In this case, it's possible to call to add or override a provider type mapping: + +[!code-csharp[Main](../../../samples/core/Modeling/BulkConfiguration/PreConventionContext.cs?name=DefaultTypeMapping)] + +### Limitations of pre-convention configuration + +- Many aspects cannot be configured with this approach. [#6787](https://github.com/dotnet/efcore/issues/6787) will expand this to more types. +- Currently the configuration is only determined by the CLR type. [#20418](https://github.com/dotnet/efcore/issues/20418) would allow custom predicates. +- This configuration is performed before a model is created. If there are any conflicts that arise when applying it, the exception stack trace will not contain the `ConfigureConventions` method, so it might be harder to find the cause. diff --git a/entity-framework/core/modeling/conventions.md.stub b/entity-framework/core/modeling/conventions.md.stub deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/entity-framework/core/providers/cosmos/unstructured-data.md b/entity-framework/core/providers/cosmos/unstructured-data.md index c2ea3d2e38..5df00805ed 100644 --- a/entity-framework/core/providers/cosmos/unstructured-data.md +++ b/entity-framework/core/providers/cosmos/unstructured-data.md @@ -13,7 +13,7 @@ EF Core was designed to make it easy to work with data that follows a schema def It is possible to access the properties that are not tracked by EF Core through a special property in [shadow-state](xref:core/modeling/shadow-properties) named `"__jObject"` that contains a `JObject` representing the data received from the store and data that will be stored: -[!code-csharp[Unmapped](../../../../samples/core/Cosmos/UnstructuredData/Sample.cs?highlight=23,24&name=Unmapped)] +[!code-csharp[Unmapped](../../../../samples/core/Cosmos/UnstructuredData/Sample.cs?highlight=21,22&name=Unmapped)] ```json { diff --git a/entity-framework/toc.yml b/entity-framework/toc.yml index d378102662..3e04e9ff8a 100644 --- a/entity-framework/toc.yml +++ b/entity-framework/toc.yml @@ -137,12 +137,13 @@ href: core/modeling/owned-entities.md - name: Keyless entity types href: core/modeling/keyless-entity-types.md - - name: Alternating models with same DbContext - href: core/modeling/dynamic-model.md - name: Spatial data displayName: GIS href: core/modeling/spatial.md - #- name: Conventions + - name: Bulk configuration + href: core/modeling/bulk-configuration.md + - name: Alternating models with same DbContext + href: core/modeling/dynamic-model.md - name: Manage database schemas items: diff --git a/samples/core/Modeling/BulkConfiguration/BulkConfiguration.csproj b/samples/core/Modeling/BulkConfiguration/BulkConfiguration.csproj new file mode 100644 index 0000000000..18404c9768 --- /dev/null +++ b/samples/core/Modeling/BulkConfiguration/BulkConfiguration.csproj @@ -0,0 +1,14 @@ + + + + Exe + net6.0 + EFModeling.BulkConfiguration + EFModeling.BulkConfiguration + + + + + + + diff --git a/samples/core/Modeling/BulkConfiguration/Currency.cs b/samples/core/Modeling/BulkConfiguration/Currency.cs new file mode 100644 index 0000000000..8ab8000939 --- /dev/null +++ b/samples/core/Modeling/BulkConfiguration/Currency.cs @@ -0,0 +1,15 @@ +namespace EFModeling.BulkConfiguration +{ + #region Currency + public readonly struct Currency + { + public Currency(decimal amount) + => Amount = amount; + + public decimal Amount { get; } + + public override string ToString() + => $"${Amount}"; + } + #endregion +} diff --git a/samples/core/Modeling/BulkConfiguration/CurrencyConverter.cs b/samples/core/Modeling/BulkConfiguration/CurrencyConverter.cs new file mode 100644 index 0000000000..291c3f5ad1 --- /dev/null +++ b/samples/core/Modeling/BulkConfiguration/CurrencyConverter.cs @@ -0,0 +1,16 @@ +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace EFModeling.BulkConfiguration +{ + #region CurrencyConverter + public class CurrencyConverter : ValueConverter + { + public CurrencyConverter() + : base( + v => v.Amount, + v => new Currency(v)) + { + } + } + #endregion +} diff --git a/samples/core/Modeling/BulkConfiguration/MetadataAPIContext.cs b/samples/core/Modeling/BulkConfiguration/MetadataAPIContext.cs new file mode 100644 index 0000000000..ede9224843 --- /dev/null +++ b/samples/core/Modeling/BulkConfiguration/MetadataAPIContext.cs @@ -0,0 +1,33 @@ +using System; +using Microsoft.EntityFrameworkCore; + +namespace EFModeling.BulkConfiguration +{ + public class MetadataAPIContext : DbContext + { + public DbSet Products { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + #region MetadataAPI + foreach (var entityType in modelBuilder.Model.GetEntityTypes()) + { + foreach (var propertyInfo in entityType.ClrType.GetProperties()) + { + if (propertyInfo.PropertyType == typeof(Currency)) + { + entityType.AddProperty(propertyInfo) + .SetValueConverter(typeof(CurrencyConverter)); + } + } + } + #endregion + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + => optionsBuilder.UseSqlServer( + @"Server=(localdb)\mssqllocaldb;Database=EFModeling.BulkConfiguration;Trusted_Connection=True") + .LogTo(Console.WriteLine, minimumLevel: Microsoft.Extensions.Logging.LogLevel.Information) + .EnableSensitiveDataLogging(); + } +} diff --git a/samples/core/Modeling/BulkConfiguration/PreConventionContext.cs b/samples/core/Modeling/BulkConfiguration/PreConventionContext.cs new file mode 100644 index 0000000000..9addd74c43 --- /dev/null +++ b/samples/core/Modeling/BulkConfiguration/PreConventionContext.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore; + +namespace EFModeling.BulkConfiguration +{ + public class PreConventionContext : DbContext + { + public DbSet Products { get; set; } + + protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder) + { + #region CurrencyConversion + configurationBuilder + .Properties() + .HaveConversion(); + #endregion + + #region StringFacets + configurationBuilder + .Properties() + .AreUnicode(false) + .HaveMaxLength(1024); + #endregion + + #region IgnoreInterface + configurationBuilder + .IgnoreAny(typeof(IList<>)); + #endregion + + #region DefaultTypeMapping + configurationBuilder + .DefaultTypeMapping() + .HasConversion(); + #endregion + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + => optionsBuilder.UseSqlServer( + @"Server=(localdb)\mssqllocaldb;Database=EFModeling.BulkConfiguration;Trusted_Connection=True") + .LogTo(Console.WriteLine, minimumLevel: Microsoft.Extensions.Logging.LogLevel.Information) + .EnableSensitiveDataLogging(); + } +} diff --git a/samples/core/Modeling/BulkConfiguration/Product.cs b/samples/core/Modeling/BulkConfiguration/Product.cs new file mode 100644 index 0000000000..25bee4222b --- /dev/null +++ b/samples/core/Modeling/BulkConfiguration/Product.cs @@ -0,0 +1,8 @@ +namespace EFModeling.BulkConfiguration +{ + public class Product + { + public int Id { get; set; } + public Currency Price { get; set; } + } +} diff --git a/samples/core/Modeling/BulkConfiguration/Program.cs b/samples/core/Modeling/BulkConfiguration/Program.cs new file mode 100644 index 0000000000..b4008c647b --- /dev/null +++ b/samples/core/Modeling/BulkConfiguration/Program.cs @@ -0,0 +1,51 @@ +using System; +using System.Linq; +using Microsoft.EntityFrameworkCore; + +namespace EFModeling.BulkConfiguration +{ + internal class Program + { + private static void Main() + { + Console.WriteLine("Sample showing bulk configuration of value conversion for a simple value object"); + Console.WriteLine(); + + using (var context = new MetadataAPIContext()) + { + RoundtripValue(context); + } + + using (var context = new PreConventionContext()) + { + RoundtripValue(context); + } + + Console.WriteLine(); + Console.WriteLine("Sample finished."); + } + + private static void RoundtripValue(DbContext context) + { + Console.WriteLine("Using " + context.GetType().Name); + Console.WriteLine("Deleting and re-creating database..."); + Console.WriteLine(); + context.Database.EnsureDeleted(); + context.Database.EnsureCreated(); + Console.WriteLine(); + Console.WriteLine("Done. Database is clean and fresh."); + + var product = new Product { Price = new Currency(3.99m) }; + context.Add(product); + + Console.WriteLine("Save a new product with price: " + product.Price.Amount); + Console.WriteLine(); + + context.SaveChanges(); + + Console.WriteLine(); + Console.WriteLine("Read the entity back with price: " + context.Set().Single().Price.Amount); + Console.WriteLine(); + } + } +} diff --git a/samples/core/Samples.sln b/samples/core/Samples.sln index 072f0da289..7f4103cde8 100644 --- a/samples/core/Samples.sln +++ b/samples/core/Samples.sln @@ -1,8 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29230.47 -MinimumVisualStudioVersion = 10.0.40219.1 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31815.197 +MinimumVisualStudioVersion = 17.0.31815.197 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Testing", "Testing", "{4E2B02EE-0C76-42D6-BA0A-337D7680A5D6}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Miscellaneous", "Miscellaneous", "{85AFD7F1-6943-40FE-B8EC-AA9DBB42CCA6}" @@ -119,61 +119,63 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfiguringDbContext", "Mis EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UserDefinedFunctionMapping", "Querying\UserDefinedFunctionMapping\UserDefinedFunctionMapping.csproj", "{11AB574E-5DA9-4C37-A342-41B3DB5D7C0D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmarks", "Benchmarks\Benchmarks.csproj", "{7CC1CD44-6C02-4736-9A6D-B3F2E987CBCB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "Benchmarks\Benchmarks.csproj", "{7CC1CD44-6C02-4736-9A6D-B3F2E987CBCB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Performance", "Performance\Performance.csproj", "{A870AAA4-EAF1-4F7D-A71E-83B20219EF6C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Performance", "Performance\Performance.csproj", "{A870AAA4-EAF1-4F7D-A71E-83B20219EF6C}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ChangeTracking", "ChangeTracking", "{F55D545B-2B45-47A5-8C55-39F972528400}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChangeTrackingInEFCore", "ChangeTracking\ChangeTrackingInEFCore\ChangeTrackingInEFCore.csproj", "{81D6316C-B612-418E-9DA1-013A9D3881BF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChangeTrackingInEFCore", "ChangeTracking\ChangeTrackingInEFCore\ChangeTrackingInEFCore.csproj", "{81D6316C-B612-418E-9DA1-013A9D3881BF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AccessingTrackedEntities", "ChangeTracking\AccessingTrackedEntities\AccessingTrackedEntities.csproj", "{0EBD2D46-533A-4DEA-A37A-453908975B9D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AccessingTrackedEntities", "ChangeTracking\AccessingTrackedEntities\AccessingTrackedEntities.csproj", "{0EBD2D46-533A-4DEA-A37A-453908975B9D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChangingFKsAndNavigations", "ChangeTracking\ChangingFKsAndNavigations\ChangingFKsAndNavigations.csproj", "{45C2F9E0-76D3-4C4A-8B3F-9465393D4155}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChangingFKsAndNavigations", "ChangeTracking\ChangingFKsAndNavigations\ChangingFKsAndNavigations.csproj", "{45C2F9E0-76D3-4C4A-8B3F-9465393D4155}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChangeDetectionAndNotifications", "ChangeTracking\ChangeDetectionAndNotifications\ChangeDetectionAndNotifications.csproj", "{0D3C4BCC-5F19-4864-A794-2823DAD22917}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChangeDetectionAndNotifications", "ChangeTracking\ChangeDetectionAndNotifications\ChangeDetectionAndNotifications.csproj", "{0D3C4BCC-5F19-4864-A794-2823DAD22917}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IdentityResolutionInEFCore", "ChangeTracking\IdentityResolutionInEFCore\IdentityResolutionInEFCore.csproj", "{6BC461D1-C015-4350-9DA8-F2468D71F718}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IdentityResolutionInEFCore", "ChangeTracking\IdentityResolutionInEFCore\IdentityResolutionInEFCore.csproj", "{6BC461D1-C015-4350-9DA8-F2468D71F718}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdditionalChangeTrackingFeatures", "ChangeTracking\AdditionalChangeTrackingFeatures\AdditionalChangeTrackingFeatures.csproj", "{B696F0AC-5282-4E95-9043-A177E3A9C5C0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AdditionalChangeTrackingFeatures", "ChangeTracking\AdditionalChangeTrackingFeatures\AdditionalChangeTrackingFeatures.csproj", "{B696F0AC-5282-4E95-9043-A177E3A9C5C0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChangeTrackerDebugging", "ChangeTracking\ChangeTrackerDebugging\ChangeTrackerDebugging.csproj", "{D1AB173F-582D-43C3-9EC0-20CE9FECFEB6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChangeTrackerDebugging", "ChangeTracking\ChangeTrackerDebugging\ChangeTrackerDebugging.csproj", "{D1AB173F-582D-43C3-9EC0-20CE9FECFEB6}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NullSemantics", "Querying\NullSemantics\NullSemantics.csproj", "{A241ED91-DE41-4310-B7CD-802F4304F27D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CascadeDeletes", "CascadeDeletes\CascadeDeletes.csproj", "{1F72C1AD-D6E1-4F06-B0C7-B04B57DA22B6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CascadeDeletes", "CascadeDeletes\CascadeDeletes.csproj", "{1F72C1AD-D6E1-4F06-B0C7-B04B57DA22B6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NewInEFCore6", "Miscellaneous\NewInEFCore6\NewInEFCore6.csproj", "{DADCEB89-6242-4A40-A390-0D957E02D426}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NewInEFCore6", "Miscellaneous\NewInEFCore6\NewInEFCore6.csproj", "{DADCEB89-6242-4A40-A390-0D957E02D426}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NewInEFCore6.Cosmos", "Miscellaneous\NewInEFCore6.Cosmos\NewInEFCore6.Cosmos.csproj", "{9614B4D9-08B7-4DA1-AF92-5B640C3C4E3D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NewInEFCore6.Cosmos", "Miscellaneous\NewInEFCore6.Cosmos\NewInEFCore6.Cosmos.csproj", "{9614B4D9-08B7-4DA1-AF92-5B640C3C4E3D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CompiledModels", "Miscellaneous\CompiledModels\CompiledModels.csproj", "{E6DC981D-4404-496E-972B-8DAC5D4A56F6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompiledModels", "Miscellaneous\CompiledModels\CompiledModels.csproj", "{E6DC981D-4404-496E-972B-8DAC5D4A56F6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IndexesAndConstraints", "Modeling\IndexesAndConstraints\IndexesAndConstraints.csproj", "{56F8DE05-6E33-4DB0-A779-70164B200289}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IndexesAndConstraints", "Modeling\IndexesAndConstraints\IndexesAndConstraints.csproj", "{56F8DE05-6E33-4DB0-A779-70164B200289}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EntityTypes", "Modeling\EntityTypes\EntityTypes.csproj", "{35539488-F445-4FAC-88DF-3C3082DC5B8E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityTypes", "Modeling\EntityTypes\EntityTypes.csproj", "{35539488-F445-4FAC-88DF-3C3082DC5B8E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EntityProperties", "Modeling\EntityProperties\EntityProperties.csproj", "{3A93EF9A-A095-4BD1-89C3-95CC517B7A44}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityProperties", "Modeling\EntityProperties\EntityProperties.csproj", "{3A93EF9A-A095-4BD1-89C3-95CC517B7A44}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Keys", "Modeling\Keys\Keys.csproj", "{F443CE43-F630-4C33-BE0F-3434D823C07A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Keys", "Modeling\Keys\Keys.csproj", "{F443CE43-F630-4C33-BE0F-3434D823C07A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GeneratedProperties", "Modeling\GeneratedProperties\GeneratedProperties.csproj", "{4F1C7FAF-DD6F-4749-9D7E-4FC627BC0B90}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GeneratedProperties", "Modeling\GeneratedProperties\GeneratedProperties.csproj", "{4F1C7FAF-DD6F-4749-9D7E-4FC627BC0B90}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConcurrencyTokens", "Modeling\ConcurrencyTokens\ConcurrencyTokens.csproj", "{E4471E3B-F8F4-45BE-95E4-8CFE0E547771}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConcurrencyTokens", "Modeling\ConcurrencyTokens\ConcurrencyTokens.csproj", "{E4471E3B-F8F4-45BE-95E4-8CFE0E547771}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShadowAndIndexerProperties", "Modeling\ShadowAndIndexerProperties\ShadowAndIndexerProperties.csproj", "{E842C983-21DC-4FE4-88C0-7B75E75E6653}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShadowAndIndexerProperties", "Modeling\ShadowAndIndexerProperties\ShadowAndIndexerProperties.csproj", "{E842C983-21DC-4FE4-88C0-7B75E75E6653}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Relationships", "Modeling\Relationships\Relationships.csproj", "{8C7271CA-BD6C-4209-BD97-2A4781BB9152}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Relationships", "Modeling\Relationships\Relationships.csproj", "{8C7271CA-BD6C-4209-BD97-2A4781BB9152}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Inheritance", "Modeling\Inheritance\Inheritance.csproj", "{417F3A21-3429-41FC-86FA-9A9FCF166BCD}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Inheritance", "Modeling\Inheritance\Inheritance.csproj", "{417F3A21-3429-41FC-86FA-9A9FCF166BCD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sequences", "Modeling\Sequences\Sequences.csproj", "{B4C32942-AB77-4674-95ED-5C0D3F85768E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sequences", "Modeling\Sequences\Sequences.csproj", "{B4C32942-AB77-4674-95ED-5C0D3F85768E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BackingFields", "Modeling\BackingFields\BackingFields.csproj", "{4FA547E3-7A94-4951-8B1D-5A4C3FBB0798}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BackingFields", "Modeling\BackingFields\BackingFields.csproj", "{4FA547E3-7A94-4951-8B1D-5A4C3FBB0798}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeylessEntityTypes", "Modeling\KeylessEntityTypes\KeylessEntityTypes.csproj", "{06539D34-C8D3-4868-A925-C3FCB3C7EE1E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KeylessEntityTypes", "Modeling\KeylessEntityTypes\KeylessEntityTypes.csproj", "{06539D34-C8D3-4868-A925-C3FCB3C7EE1E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Misc", "Modeling\Misc\Misc.csproj", "{8A45191D-F719-4CFB-AB37-7A1653BCC720}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Misc", "Modeling\Misc\Misc.csproj", "{8A45191D-F719-4CFB-AB37-7A1653BCC720}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BulkConfiguration", "Modeling\BulkConfiguration\BulkConfiguration.csproj", "{FE7AB616-97A5-46D4-A8B1-B2980A8C7379}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -485,6 +487,10 @@ Global {8A45191D-F719-4CFB-AB37-7A1653BCC720}.Debug|Any CPU.Build.0 = Debug|Any CPU {8A45191D-F719-4CFB-AB37-7A1653BCC720}.Release|Any CPU.ActiveCfg = Release|Any CPU {8A45191D-F719-4CFB-AB37-7A1653BCC720}.Release|Any CPU.Build.0 = Release|Any CPU + {FE7AB616-97A5-46D4-A8B1-B2980A8C7379}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FE7AB616-97A5-46D4-A8B1-B2980A8C7379}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FE7AB616-97A5-46D4-A8B1-B2980A8C7379}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FE7AB616-97A5-46D4-A8B1-B2980A8C7379}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -561,6 +567,7 @@ Global {4FA547E3-7A94-4951-8B1D-5A4C3FBB0798} = {CA5046EC-C894-4535-8190-A31F75FDEB96} {06539D34-C8D3-4868-A925-C3FCB3C7EE1E} = {CA5046EC-C894-4535-8190-A31F75FDEB96} {8A45191D-F719-4CFB-AB37-7A1653BCC720} = {CA5046EC-C894-4535-8190-A31F75FDEB96} + {FE7AB616-97A5-46D4-A8B1-B2980A8C7379} = {CA5046EC-C894-4535-8190-A31F75FDEB96} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {20C98D35-54EF-46A6-8F3B-1855C1AE4F70}