├── .gitignore ├── MagicDbModelBuilder.Tests ├── ConfigurationRegistrarTests.cs ├── DbModelBuilderExtensionsTests.cs ├── EntityTypeConfigurationWrapperTests.cs ├── MagicDbModelBuilder.Tests.csproj ├── Model │ ├── Corn.cs │ ├── Unicorn.cs │ └── UnicornEntityTypeConfiguration.cs ├── Properties │ └── AssemblyInfo.cs └── packages.config ├── MagicDbModelBuilder.sln ├── MagicDbModelBuilder ├── ComplexTypeConfigurationWrapper.cs ├── ConfigurationRegistrarExtensions.cs ├── DbModelBuilderExtensions.cs ├── EntityTypeConfigurationWrapper.cs ├── MagicDbModelBuilder.csproj ├── Properties │ └── AssemblyInfo.cs └── StructuralTypeConfigurationWrapper.cs └── README /.gitignore: -------------------------------------------------------------------------------- 1 | #OS junk files 2 | [Tt]humbs.db 3 | *.DS_Store 4 | 5 | #Visual Studio files 6 | *.[Oo]bj 7 | *.user 8 | *.aps 9 | *.pch 10 | *.vspscc 11 | *.vssscc 12 | *_i.c 13 | *_p.c 14 | *.ncb 15 | *.suo 16 | *.tlb 17 | *.tlh 18 | *.bak 19 | *.[Cc]ache 20 | *.ilk 21 | *.log 22 | *.lib 23 | *.sbr 24 | *.sdf 25 | *.opensdf 26 | *.unsuccessfulbuild 27 | ipch/ 28 | obj/ 29 | [Bb]in 30 | [Dd]ebug*/ 31 | [Rr]elease*/ 32 | Ankh.NoLoad 33 | 34 | #Tooling 35 | _ReSharper*/ 36 | *.resharper 37 | [Tt]est[Rr]esult* 38 | 39 | #Project files 40 | [Bb]uild/ 41 | 42 | #Subversion files 43 | .svn 44 | 45 | # Office Temp Files 46 | ~$* 47 | 48 | #NuGet 49 | packages/ -------------------------------------------------------------------------------- /MagicDbModelBuilder.Tests/ConfigurationRegistrarTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Entity; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Text; 7 | using MagicDbModelBuilder.Tests.Model; 8 | using NUnit.Framework; 9 | 10 | namespace MagicDbModelBuilder.Tests 11 | { 12 | [TestFixture] 13 | public class ConfigurationRegistrarTests 14 | { 15 | private readonly DbModelBuilder _builder; 16 | 17 | public ConfigurationRegistrarTests() 18 | { 19 | _builder = new DbModelBuilder(); 20 | } 21 | 22 | [Test] 23 | public void Scan_By_Assembly() 24 | { 25 | _builder.Configurations 26 | .Scan(Assembly.GetExecutingAssembly()); 27 | 28 | Assert.That(_builder.Configurations.IsConfigured()); 29 | Assert.That(_builder.Configurations.IsConfigured(typeof(Unicorn))); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /MagicDbModelBuilder.Tests/DbModelBuilderExtensionsTests.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Entity; 2 | using System.Data.Entity.ModelConfiguration; 3 | using MagicDbModelBuilder.Tests.Model; 4 | using NUnit.Framework; 5 | 6 | namespace MagicDbModelBuilder.Tests 7 | { 8 | [TestFixture] 9 | public class DbModelBuilderExtensionsTests 10 | { 11 | private readonly DbModelBuilder _builder; 12 | 13 | public DbModelBuilderExtensionsTests() 14 | { 15 | _builder = new DbModelBuilder(); 16 | } 17 | 18 | [Test] 19 | public void Entity() 20 | { 21 | var config = _builder.Entity(typeof(Unicorn)); 22 | 23 | Assert.NotNull(config); 24 | Assert.That(config.GetType() == typeof(EntityTypeConfigurationWrapper)); 25 | Assert.That(config.TypeConfiguration.GetType() == typeof(EntityTypeConfiguration)); 26 | Assert.That(config.ConfiguredType == typeof(Unicorn)); 27 | 28 | Assert.That(_builder.Configurations.IsConfigured(typeof(Unicorn))); 29 | } 30 | 31 | [Test] 32 | public void ComplexType() 33 | { 34 | var config = _builder.ComplexType(typeof(Corn)); 35 | 36 | Assert.NotNull(config); 37 | Assert.That(config.GetType() == typeof(ComplexTypeConfigurationWrapper)); 38 | Assert.That(config.TypeConfiguration.GetType() == typeof(ComplexTypeConfiguration)); 39 | Assert.That(config.ConfiguredType == typeof(Corn)); 40 | 41 | Assert.That(_builder.Configurations.IsConfigured(typeof(Corn))); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /MagicDbModelBuilder.Tests/EntityTypeConfigurationWrapperTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Data.Entity; 5 | using System.Data.Entity.ModelConfiguration; 6 | using System.Data.Entity.ModelConfiguration.Configuration; 7 | using System.Linq; 8 | using System.Text; 9 | using MagicDbModelBuilder.Tests.Model; 10 | using NUnit.Framework; 11 | 12 | namespace MagicDbModelBuilder.Tests 13 | { 14 | [TestFixture] 15 | public class EntityTypeConfigurationWrapperTests 16 | { 17 | private readonly DbModelBuilder _builder; 18 | 19 | public EntityTypeConfigurationWrapperTests() 20 | { 21 | _builder = new DbModelBuilder(); 22 | } 23 | 24 | [Test] 25 | public void HasKey() 26 | { 27 | var config = _builder.Entity(typeof (Unicorn)) 28 | .HasKey(typeof (int), "Id"); 29 | 30 | Assert.NotNull(config); 31 | Assert.That(config.GetType() == typeof(EntityTypeConfigurationWrapper)); 32 | Assert.That(config.TypeConfiguration.GetType() == typeof(EntityTypeConfiguration)); 33 | Assert.That(config.ConfiguredType == typeof(Unicorn)); 34 | } 35 | 36 | [Test] 37 | public void Ignore() 38 | { 39 | _builder.ComplexType(typeof (Corn)) 40 | .Ignore(typeof(int), "BaseRadius"); 41 | } 42 | 43 | [Test] 44 | public void Property() 45 | { 46 | var property = _builder.Entity(typeof (Unicorn)) 47 | .PrimitiveProperty(typeof (int), "Id"); 48 | 49 | Assert.NotNull(property); 50 | Assert.That(property.GetType() == typeof(PrimitivePropertyConfiguration)); 51 | } 52 | 53 | [Test] 54 | public void Property_Supports_Nullable() 55 | { 56 | var property = _builder.Entity(typeof (Unicorn)) 57 | .PrimitiveProperty(typeof(int?), "ChildCount"); 58 | 59 | Assert.NotNull(property); 60 | Assert.That(property.GetType() == typeof(PrimitivePropertyConfiguration)); 61 | } 62 | 63 | [Test] 64 | public void Property_Can_Chain() 65 | { 66 | var property = _builder.Entity(typeof (Unicorn)) 67 | .PrimitiveProperty(typeof(int), "Id") 68 | .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 69 | 70 | Assert.NotNull(property); 71 | Assert.That(property.GetType() == typeof(PrimitivePropertyConfiguration)); 72 | } 73 | 74 | [Test] 75 | public void DateTimeProperty() 76 | { 77 | var property = _builder.Entity(typeof(Unicorn)) 78 | .DateTimeProperty("BornOn"); 79 | 80 | Assert.NotNull(property); 81 | Assert.That(property.GetType() == typeof(DateTimePropertyConfiguration)); 82 | } 83 | 84 | [Test] 85 | public void DateTimeProperty_Supports_Nullable() 86 | { 87 | var property = _builder.Entity(typeof(Unicorn)) 88 | .NullableDateTimeProperty("LastMatedOn"); 89 | 90 | Assert.NotNull(property); 91 | Assert.That(property.GetType() == typeof(DateTimePropertyConfiguration)); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /MagicDbModelBuilder.Tests/MagicDbModelBuilder.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {455FD1E8-9948-4CD5-8AC8-A0116BCDF294} 9 | Library 10 | Properties 11 | MagicDbModelBuilder.Tests 12 | MagicDbModelBuilder.Tests 13 | v4.2 14 | 512 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | ..\packages\NUnit.2.5.10.11092\lib\nunit.framework.dll 37 | 38 | 39 | ..\packages\NUnit.2.5.10.11092\lib\nunit.mocks.dll 40 | 41 | 42 | ..\packages\NUnit.2.5.10.11092\lib\pnunit.framework.dll 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | {BBD1EB27-12CB-42C5-83A6-7C03D10DEAAD} 66 | MagicDbModelBuilder 67 | 68 | 69 | 70 | 77 | -------------------------------------------------------------------------------- /MagicDbModelBuilder.Tests/Model/Corn.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace MagicDbModelBuilder.Tests.Model 7 | { 8 | public class Corn 9 | { 10 | public int Length { get; set; } 11 | public int BaseRadius { get; set; } 12 | public bool IsCracked { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MagicDbModelBuilder.Tests/Model/Unicorn.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MagicDbModelBuilder.Tests.Model 4 | { 5 | public class Unicorn 6 | { 7 | public int Id { get; set; } 8 | public int? ChildCount { get; set; } 9 | public DateTime BornOn { get; set; } 10 | public DateTime? LastMatedOn { get; set; } 11 | public Corn Corn { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MagicDbModelBuilder.Tests/Model/UnicornEntityTypeConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Entity.ModelConfiguration; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace MagicDbModelBuilder.Tests.Model 8 | { 9 | public class UnicornEntityTypeConfiguration: EntityTypeConfiguration 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MagicDbModelBuilder.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MagicDbModelBuilder.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("MagicDbModelBuilder.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2011")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("634264f6-28da-4ab5-a53f-da2750371bfd")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /MagicDbModelBuilder.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /MagicDbModelBuilder.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MagicDbModelBuilder", "MagicDbModelBuilder\MagicDbModelBuilder.csproj", "{BBD1EB27-12CB-42C5-83A6-7C03D10DEAAD}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MagicDbModelBuilder.Tests", "MagicDbModelBuilder.Tests\MagicDbModelBuilder.Tests.csproj", "{455FD1E8-9948-4CD5-8AC8-A0116BCDF294}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {BBD1EB27-12CB-42C5-83A6-7C03D10DEAAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {BBD1EB27-12CB-42C5-83A6-7C03D10DEAAD}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {BBD1EB27-12CB-42C5-83A6-7C03D10DEAAD}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {BBD1EB27-12CB-42C5-83A6-7C03D10DEAAD}.Release|Any CPU.Build.0 = Release|Any CPU 18 | {455FD1E8-9948-4CD5-8AC8-A0116BCDF294}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {455FD1E8-9948-4CD5-8AC8-A0116BCDF294}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {455FD1E8-9948-4CD5-8AC8-A0116BCDF294}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {455FD1E8-9948-4CD5-8AC8-A0116BCDF294}.Release|Any CPU.Build.0 = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /MagicDbModelBuilder/ComplexTypeConfigurationWrapper.cs: -------------------------------------------------------------------------------- 1 | namespace MagicDbModelBuilder 2 | { 3 | public class ComplexTypeConfigurationWrapper : StructuralTypeConfigurationWrapper 4 | { 5 | public ComplexTypeConfigurationWrapper(dynamic complexTypeConfiguration) 6 | : base((object)complexTypeConfiguration) 7 | { 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /MagicDbModelBuilder/ConfigurationRegistrarExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Entity.ModelConfiguration; 4 | using System.Data.Entity.ModelConfiguration.Configuration; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Text; 8 | 9 | namespace MagicDbModelBuilder 10 | { 11 | public static class ConfigurationRegistrarExtensions 12 | { 13 | public static void Scan(this ConfigurationRegistrar configurationRegistrar, Assembly assembly) 14 | { 15 | var types = assembly.GetTypes() 16 | .Where(t => t.BaseType != null 17 | && t.BaseType.IsGenericType 18 | && t.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>)); 19 | 20 | foreach(var t in types) 21 | { 22 | dynamic config = Activator.CreateInstance(t); 23 | configurationRegistrar.Add(config); 24 | } 25 | } 26 | 27 | public static bool IsConfigured(this ConfigurationRegistrar configurationRegistrar) 28 | { 29 | return configurationRegistrar.IsConfigured(typeof(T)); 30 | } 31 | 32 | public static bool IsConfigured(this ConfigurationRegistrar configurationRegistrar, Type type) 33 | { 34 | var configuredTypes = (IEnumerable)configurationRegistrar 35 | .GetType() 36 | .GetMethod("GetConfiguredTypes", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) 37 | .Invoke(configurationRegistrar, null); 38 | return configuredTypes.Any(t => t == type); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /MagicDbModelBuilder/DbModelBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Entity; 3 | 4 | namespace MagicDbModelBuilder 5 | { 6 | public static class DbModelBuilderExtensions 7 | { 8 | public static EntityTypeConfigurationWrapper Entity(this DbModelBuilder builder, Type entityType) 9 | { 10 | var config = builder.GetType() 11 | .GetMethod("Entity") 12 | .MakeGenericMethod(entityType) 13 | .Invoke(builder, null); 14 | return new EntityTypeConfigurationWrapper(config); 15 | } 16 | 17 | public static ComplexTypeConfigurationWrapper ComplexType(this DbModelBuilder builder, Type entityType) 18 | { 19 | var config = builder.GetType() 20 | .GetMethod("ComplexType") 21 | .MakeGenericMethod(entityType) 22 | .Invoke(builder, null); 23 | return new ComplexTypeConfigurationWrapper(config); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MagicDbModelBuilder/EntityTypeConfigurationWrapper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Entity.ModelConfiguration.Configuration; 3 | using System.Linq; 4 | using System.Linq.Expressions; 5 | using System.Reflection; 6 | 7 | namespace MagicDbModelBuilder 8 | { 9 | public class EntityTypeConfigurationWrapper: StructuralTypeConfigurationWrapper 10 | { 11 | public EntityTypeConfigurationWrapper(dynamic entityTypeConfiguration) 12 | : base((object)entityTypeConfiguration) 13 | { 14 | } 15 | 16 | public EntityTypeConfigurationWrapper HasKey(Type keyType, params string[] propertyNames) 17 | { 18 | if (propertyNames.Length > 1) 19 | throw new NotImplementedException(); 20 | 21 | var paramEx = Expression.Parameter(Type, "x"); 22 | var lambdaEx = Expression.Lambda(Expression.Property(paramEx, propertyNames[0]), paramEx); 23 | 24 | Config.GetType() 25 | .GetMethod("HasKey") 26 | .MakeGenericMethod(keyType) 27 | .Invoke(Config, new[] { lambdaEx }); 28 | 29 | return this; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /MagicDbModelBuilder/MagicDbModelBuilder.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {BBD1EB27-12CB-42C5-83A6-7C03D10DEAAD} 9 | Library 10 | Properties 11 | MagicDbModelBuilder 12 | MagicDbModelBuilder 13 | v4.2 14 | 512 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 60 | -------------------------------------------------------------------------------- /MagicDbModelBuilder/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DbModelBuilderWrapper")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Maxime Beaudoin")] 12 | [assembly: AssemblyProduct("DbModelBuilderWrapper")] 13 | [assembly: AssemblyCopyright("Copyright © Maxime Beaudoin 2011")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("3edcd789-b3f0-4470-aae9-eb79afb86381")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /MagicDbModelBuilder/StructuralTypeConfigurationWrapper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Entity.ModelConfiguration.Configuration; 4 | using System.Data.Spatial; 5 | using System.Linq; 6 | using System.Linq.Expressions; 7 | using System.Reflection; 8 | using System.Text; 9 | 10 | namespace MagicDbModelBuilder 11 | { 12 | public abstract class StructuralTypeConfigurationWrapper 13 | { 14 | protected readonly dynamic Config; 15 | protected readonly Type Type; 16 | 17 | public dynamic TypeConfiguration { get { return Config; } } 18 | public Type ConfiguredType { get { return Type; } } 19 | 20 | protected StructuralTypeConfigurationWrapper(dynamic typeConfiguration) 21 | { 22 | Config = typeConfiguration; 23 | Type = typeConfiguration.GetType().GetGenericArguments()[0]; 24 | } 25 | 26 | public void Ignore(Type propertyType, string propertyName) 27 | { 28 | var paramEx = Expression.Parameter(Type, "x"); 29 | var lambdaEx = Expression.Lambda(Expression.Property(paramEx, propertyName), paramEx); 30 | 31 | Config.GetType() 32 | .GetMethod("Ignore") 33 | .MakeGenericMethod(propertyType) 34 | .Invoke(Config, new[] { lambdaEx }); 35 | } 36 | 37 | public dynamic DynamicProperty(Type propertyType, string propertyName) 38 | { 39 | var exType = typeof(Expression<>) 40 | .MakeGenericType(typeof(Func<,>) 41 | .MakeGenericType(Type, propertyType)); 42 | 43 | var paramEx = Expression.Parameter(Type, "x"); 44 | var lambdaEx = Expression.Lambda(Expression.Property(paramEx, propertyName), paramEx); 45 | 46 | 47 | return Config.GetType() 48 | .GetMethod("Property", new[] { exType }) 49 | .Invoke(Config, new[] { lambdaEx }); 50 | } 51 | 52 | public PrimitivePropertyConfiguration PrimitiveProperty(Type propertyType, string propertyName) 53 | { 54 | var typeIsNullable = propertyType.IsGenericType && 55 | propertyType.GetGenericTypeDefinition() == typeof(Nullable<>); 56 | 57 | MethodInfo[] methods = Config.GetType().GetMethods(); 58 | var candidates = methods.Where(m => m.Name == "Property" && m.IsGenericMethod); 59 | 60 | var property = candidates.First(m => 61 | { 62 | var param = m.GetParameters()[0]; 63 | var type = param.ParameterType; // Expression<> 64 | var func = type.GetGenericArguments()[0]; // Func<,> 65 | var T = func.GetGenericArguments()[1]; // T or T? 66 | var isNullable = T.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable<>); 67 | return (typeIsNullable && isNullable) || (!typeIsNullable && !isNullable); 68 | }); 69 | 70 | var paramEx = Expression.Parameter(Type, "x"); 71 | var lambdaEx = Expression.Lambda(Expression.Property(paramEx, propertyName), paramEx); 72 | 73 | var nonNullableType = typeIsNullable ? propertyType.GetGenericArguments()[0] : propertyType; 74 | 75 | return property 76 | .MakeGenericMethod(nonNullableType) 77 | .Invoke(Config, new[] { lambdaEx }); 78 | } 79 | 80 | public DateTimePropertyConfiguration DateTimeProperty(string propertyName) 81 | { 82 | return DynamicProperty(typeof (DateTime), propertyName); 83 | } 84 | 85 | public DateTimePropertyConfiguration NullableDateTimeProperty(string propertyName) 86 | { 87 | return DynamicProperty(typeof (DateTime?), propertyName); 88 | } 89 | 90 | public StringPropertyConfiguration StringProperty(string propertyName) 91 | { 92 | return DynamicProperty(typeof(string), propertyName); 93 | } 94 | 95 | public BinaryPropertyConfiguration BinaryProperty(string propertyName) 96 | { 97 | return DynamicProperty(typeof(byte[]), propertyName); 98 | } 99 | 100 | public DecimalPropertyConfiguration DecimalProperty(string propertyName) 101 | { 102 | return DynamicProperty(typeof(decimal), propertyName); 103 | } 104 | 105 | public DecimalPropertyConfiguration NullableDecimalProperty(string propertyName) 106 | { 107 | return DynamicProperty(typeof(Decimal?), propertyName); 108 | } 109 | 110 | public DateTimePropertyConfiguration DateTimeOffsetProperty(string propertyName) 111 | { 112 | return DynamicProperty(typeof(DateTimeOffset), propertyName); 113 | } 114 | 115 | public DateTimePropertyConfiguration NullableDateTimeOffsetProperty(string propertyName) 116 | { 117 | return DynamicProperty(typeof(DateTimeOffset?), propertyName); 118 | } 119 | 120 | public DateTimePropertyConfiguration TimeSpanProperty(string propertyName) 121 | { 122 | return DynamicProperty(typeof(TimeSpan), propertyName); 123 | } 124 | 125 | public DateTimePropertyConfiguration NullableTimeSpanProperty(string propertyName) 126 | { 127 | return DynamicProperty(typeof(TimeSpan?), propertyName); 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | MagicDbModelBuilder is a set of wrapper classes that enable the creation/configuration of models at runtime 2 | through reflection. A feature that Entity Framework does not support, for now. 3 | 4 | What you could do: 5 | 6 | var builder = new DbModelBuilder(); 7 | builder.Entity() 8 | .HasKey(p => p.Id); 9 | 10 | ... what you couldn't do: 11 | 12 | var builder = new DbModelBuilder(); 13 | builder.Entity(typeof(Post)) 14 | .HasKey(typeof(Guid), "Id"); 15 | 16 | ... or ... 17 | 18 | builder.Entity(typeof(Post)) 19 | .Property(typeof(int), "Id") 20 | .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 21 | 22 | ... or ... 23 | 24 | builder.Entity(typeof(Post)) 25 | .DateTimeProperty("ModifiedOn", true) // supports nullable with optional parameter 'nullable' set to true 26 | .IsRequired(); 27 | 28 | More implementations to come... --------------------------------------------------------------------------------