Skip to content
This repository has been archived by the owner on Jan 16, 2024. It is now read-only.

Commit

Permalink
Dependent type enhancements
Browse files Browse the repository at this point in the history
  • Loading branch information
msawczyn committed Oct 2, 2020
1 parent b112a03 commit 62f87c3
Show file tree
Hide file tree
Showing 14 changed files with 360 additions and 263 deletions.
320 changes: 170 additions & 150 deletions src/Dsl/CustomCode/Rules/ModelClassChangeRules.cs

Large diffs are not rendered by default.

Expand Up @@ -27,8 +27,13 @@ private PropertyDescriptorCollection GetCustomProperties(Attribute[] attributes)

// no property bags if pre-EFCore5
if (!modelRoot.IsEFCore5Plus)
{
propertyDescriptors.Remove("IsPropertyBag");

if (modelClass.IsDependentType && modelRoot.EntityFrameworkVersion == EFVersion.EF6)
propertyDescriptors.Remove("TableName");
}

//Add the descriptors for the tracking properties

propertyDescriptors.Add(new TrackingPropertyDescriptor(modelClass
Expand Down
10 changes: 5 additions & 5 deletions src/Dsl/Dsl.csproj
Expand Up @@ -551,18 +551,18 @@
<Version>1.2.0</Version>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis">
<Version>3.5.0</Version>
<Version>3.8.0-3.final</Version>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers">
<Version>3.0.0</Version>
<Version>3.3.0</Version>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
<Version>12.0.3</Version>
</PackageReference>
<PackageReference Include="SQLitePCLRaw.bundle_green">
<Version>2.0.2</Version>
<Version>2.0.4</Version>
</PackageReference>
<PackageReference Include="SQLitePCLRaw.lib.e_sqlite3.linux">
<Version>1.1.14</Version>
Expand All @@ -586,7 +586,7 @@
<Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Composition">
<Version>1.4.0</Version>
<Version>5.0.0-rc.1.20451.14</Version>
</PackageReference>
<PackageReference Include="System.Console">
<Version>4.3.1</Version>
Expand Down Expand Up @@ -661,7 +661,7 @@
<Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="System.Text.Encoding.CodePages">
<Version>4.7.0</Version>
<Version>5.0.0-rc.1.20451.14</Version>
</PackageReference>
<PackageReference Include="System.Text.Encoding.Extensions">
<Version>4.3.0</Version>
Expand Down
8 changes: 4 additions & 4 deletions src/DslPackage/DslPackage.csproj
Expand Up @@ -452,21 +452,21 @@ if "$(ConfigurationName)"=="Release" del "$(ProjectDir)Parsers\*.pdb
</ItemGroup>
<ItemGroup>
<PackageReference Include="EnvDTE80">
<Version>8.0.3</Version>
<Version>16.7.30328.74</Version>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.SDK.EmbedInteropTypes">
<Version>15.0.29</Version>
<Version>15.0.34</Version>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop.12.0">
<Version>12.0.30111</Version>
<Version>16.7.30328.74</Version>
</PackageReference>
<PackageReference Include="QuikGraph" Version="2.2.0" />
<PackageReference Include="QuikGraph.Graphviz" Version="2.2.0" />
<PackageReference Include="Shields.GraphViz">
<Version>1.0.2</Version>
</PackageReference>
<PackageReference Include="stdole">
<Version>7.0.3303</Version>
<Version>16.7.30508.193</Version>
</PackageReference>
<PackageReference Include="System.Runtime">
<Version>4.3.1</Version>
Expand Down
Binary file modified src/DslPackage/Parsers/EF6Parser.exe
Binary file not shown.
Binary file modified src/DslPackage/Parsers/EFCore2Parser.exe
Binary file not shown.
Binary file modified src/DslPackage/Parsers/EFCore3Parser.exe
Binary file not shown.
90 changes: 41 additions & 49 deletions src/DslPackage/TextTemplates/EFCoreDesigner.ttinclude
Expand Up @@ -129,17 +129,17 @@
switch (modelRoot.InheritanceStrategy)
{
case CodeStrategy.TablePerType:
classesWithTables = modelRoot.Classes.Where(mc => !mc.IsDependentType && mc.GenerateCode).OrderBy(x => x.Name).ToArray();
classesWithTables = modelRoot.Classes.Where(mc => (!mc.IsDependentType || !string.IsNullOrEmpty(mc.TableName)) && mc.GenerateCode).OrderBy(x => x.Name).ToArray();

break;

case CodeStrategy.TablePerConcreteType:
classesWithTables = modelRoot.Classes.Where(mc => !mc.IsDependentType && !mc.IsAbstract && mc.GenerateCode).OrderBy(x => x.Name).ToArray();
classesWithTables = modelRoot.Classes.Where(mc => (!mc.IsDependentType || !string.IsNullOrEmpty(mc.TableName)) && !mc.IsAbstract && mc.GenerateCode).OrderBy(x => x.Name).ToArray();

break;

case CodeStrategy.TablePerHierarchy:
classesWithTables = modelRoot.Classes.Where(mc => !mc.IsDependentType && mc.Superclass == null && mc.GenerateCode).OrderBy(x => x.Name).ToArray();
classesWithTables = modelRoot.Classes.Where(mc => (!mc.IsDependentType || !string.IsNullOrEmpty(mc.TableName)) && mc.Superclass == null && mc.GenerateCode).OrderBy(x => x.Name).ToArray();

break;
}
Expand Down Expand Up @@ -298,39 +298,35 @@
{
// class level

bool isDependent = modelClass.IsDependentType;
segments.Add($"modelBuilder.{(isDependent ? "Owned" : "Entity")}<{modelClass.FullName}>()");
segments.Add($"modelBuilder.{(modelClass.IsDependentType ? "Owned" : "Entity")}<{modelClass.FullName}>()");

foreach (ModelAttribute transient in modelClass.Attributes.Where(x => !x.Persistent))
segments.Add($"Ignore(t => t.{transient.Name})");

if (!modelClass.IsDependentType)
{
// note: this must come before the 'ToTable' call or there's a runtime error
if (modelRoot.InheritanceStrategy == CodeStrategy.TablePerConcreteType && modelClass.Superclass != null)
segments.Add("Map(x => x.MapInheritedProperties())");
// note: this must come before the 'ToTable' call or there's a runtime error
if (modelRoot.InheritanceStrategy == CodeStrategy.TablePerConcreteType && modelClass.Superclass != null)
segments.Add("Map(x => x.MapInheritedProperties())");

if (classesWithTables.Contains(modelClass))
{
segments.Add(string.IsNullOrEmpty(modelClass.DatabaseSchema) || modelClass.DatabaseSchema == modelClass.ModelRoot.DatabaseSchema
? $"ToTable(\"{modelClass.TableName}\")"
: $"ToTable(\"{modelClass.TableName}\", \"{modelClass.DatabaseSchema}\")");
if (classesWithTables.Contains(modelClass))
{
segments.Add(string.IsNullOrEmpty(modelClass.DatabaseSchema) || modelClass.DatabaseSchema == modelClass.ModelRoot.DatabaseSchema
? $"ToTable(\"{modelClass.TableName}\")"
: $"ToTable(\"{modelClass.TableName}\", \"{modelClass.DatabaseSchema}\")");

// primary key code segments must be output last, since HasKey returns a different type
List<ModelAttribute> identityAttributes = modelClass.IdentityAttributes.ToList();
// primary key code segments must be output last, since HasKey returns a different type
List<ModelAttribute> identityAttributes = modelClass.IdentityAttributes.ToList();

if (identityAttributes.Count == 1)
segments.Add($"HasKey(t => t.{identityAttributes[0].Name})");
else if (identityAttributes.Count > 1)
segments.Add($"HasKey(t => new {{ t.{string.Join(", t.", identityAttributes.Select(ia => ia.Name))} }})");
}
if (identityAttributes.Count == 1)
segments.Add($"HasKey(t => t.{identityAttributes[0].Name})");
else if (identityAttributes.Count > 1)
segments.Add($"HasKey(t => new {{ t.{string.Join(", t.", identityAttributes.Select(ia => ia.Name))} }})");
}

if (segments.Count > 1 || modelClass.IsDependentType)
Output(modelRoot, segments);

if (modelClass.IsDependentType)
return;
//if (modelClass.IsDependentType)
// return;

// attribute level
foreach (ModelAttribute modelAttribute in modelClass.Attributes.Where(x => x.Persistent && !SpatialTypesEFCore.Contains(x.Type)))
Expand Down Expand Up @@ -459,7 +455,7 @@
// ReSharper disable once LoopCanBePartlyConvertedToQuery
foreach (UnidirectionalAssociation association in Association.GetLinksToTargets(modelClass)
.OfType<UnidirectionalAssociation>()
.Where(x => x.Persistent && !x.Target.IsDependentType))
.Where(x => x.Persistent))
{
if (visited.Contains(association))
continue;
Expand Down Expand Up @@ -593,15 +589,15 @@
}
}

foreach (UnidirectionalAssociation association in Association.GetLinksToTargets(modelClass)
.OfType<UnidirectionalAssociation>()
.Where(x => x.Persistent && x.Target.IsDependentType))
{
if (association.TargetMultiplicity == Sawczyn.EFDesigner.EFModel.Multiplicity.ZeroOne || association.TargetMultiplicity == Sawczyn.EFDesigner.EFModel.Multiplicity.One)
Output($"modelBuilder.Entity<{modelClass.FullName}>().OwnsOne(x => x.{association.TargetPropertyName});");
else
Output($"// Dependent 1-many association seen ({association.TargetPropertyName}). Code generation still unsupported in designer.");
}
//foreach (UnidirectionalAssociation association in Association.GetLinksToTargets(modelClass)
// .OfType<UnidirectionalAssociation>()
// .Where(x => x.Persistent))
//{
// if (association.TargetMultiplicity == Sawczyn.EFDesigner.EFModel.Multiplicity.ZeroOne || association.TargetMultiplicity == Sawczyn.EFDesigner.EFModel.Multiplicity.One)
// Output($"modelBuilder.Entity<{modelClass.FullName}>().OwnsOne(x => x.{association.TargetPropertyName});");
// else
// Output($"// Dependent 1-many association seen ({association.TargetPropertyName}). Code generation still unsupported in designer.");
//}

// ReSharper disable once LoopCanBePartlyConvertedToQuery
foreach (BidirectionalAssociation association in Association.GetLinksToSources(modelClass)
Expand Down Expand Up @@ -706,8 +702,7 @@
{
// class level

bool isDependent = modelClass.IsDependentType;
segments.Add($"modelBuilder.{(isDependent ? "Owned" : "Entity")}<{modelClass.FullName}>()");
segments.Add($"modelBuilder.{(modelClass.IsDependentType ? "Owned" : "Entity")}<{modelClass.FullName}>()");

foreach (ModelAttribute transient in modelClass.Attributes.Where(x => !x.Persistent))
segments.Add($"Ignore(t => t.{transient.Name})");
Expand Down Expand Up @@ -737,9 +732,6 @@
if (segments.Count > 1 || modelClass.IsDependentType)
Output(modelRoot, segments);

if (modelClass.IsDependentType)
return;

// attribute level
foreach (ModelAttribute modelAttribute in modelClass.Attributes.Where(x => x.Persistent && !SpatialTypesEFCore.Contains(x.Type)))
{
Expand Down Expand Up @@ -867,7 +859,7 @@
// ReSharper disable once LoopCanBePartlyConvertedToQuery
foreach (UnidirectionalAssociation association in Association.GetLinksToTargets(modelClass)
.OfType<UnidirectionalAssociation>()
.Where(x => x.Persistent && !x.Target.IsDependentType))
.Where(x => x.Persistent))
{
if (visited.Contains(association))
continue;
Expand Down Expand Up @@ -1001,15 +993,15 @@
}
}

foreach (UnidirectionalAssociation association in Association.GetLinksToTargets(modelClass)
.OfType<UnidirectionalAssociation>()
.Where(x => x.Persistent && x.Target.IsDependentType))
{
if (association.TargetMultiplicity == Sawczyn.EFDesigner.EFModel.Multiplicity.ZeroOne || association.TargetMultiplicity == Sawczyn.EFDesigner.EFModel.Multiplicity.One)
Output($"modelBuilder.Entity<{modelClass.FullName}>().OwnsOne(x => x.{association.TargetPropertyName});");
else
Output($"// Dependent 1-many association seen ({association.TargetPropertyName}). Code generation still unsupported in designer.");
}
//foreach (UnidirectionalAssociation association in Association.GetLinksToTargets(modelClass)
// .OfType<UnidirectionalAssociation>()
// .Where(x => x.Persistent && x.Target.IsDependentType))
//{
// if (association.TargetMultiplicity == Sawczyn.EFDesigner.EFModel.Multiplicity.ZeroOne || association.TargetMultiplicity == Sawczyn.EFDesigner.EFModel.Multiplicity.One)
// Output($"modelBuilder.Entity<{modelClass.FullName}>().OwnsOne(x => x.{association.TargetPropertyName});");
// else
// Output($"// Dependent 1-many association seen ({association.TargetPropertyName}). Code generation still unsupported in designer.");
//}

// ReSharper disable once LoopCanBePartlyConvertedToQuery
foreach (BidirectionalAssociation association in Association.GetLinksToSources(modelClass)
Expand Down

0 comments on commit 62f87c3

Please sign in to comment.