Skip to content

Commit

Permalink
fix(efcore5): correct validation when table mapping is unset
Browse files Browse the repository at this point in the history
  • Loading branch information
jayharris committed Jan 22, 2022
1 parent c9c77a1 commit 3d6ff24
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 19 deletions.
Expand Up @@ -26,11 +26,11 @@ public class SchemaValidator {

foreach (var persistedType in persistedTypes) {
if (databaseModel.GetView(persistedType) == null &&
persistedType.FindAnnotation(RelationalAnnotationNames.ViewName) != null) {
persistedType.FindAnnotation(RelationalAnnotationNames.ViewName)?.Value != null) {
validationErrors.Add($"Missing view: {persistedType.GetViewName()}");
}

if (persistedType.FindAnnotation(RelationalAnnotationNames.TableName) == null) {
if (persistedType.FindAnnotation(RelationalAnnotationNames.TableName)?.Value == null) {
continue;
}

Expand Down Expand Up @@ -61,25 +61,45 @@ public class SchemaValidator {
var valErrors = new List<string>();
foreach (var persistedColumn in persistedType.GetProperties()) {
var dbColumn = databaseModel.GetTableColumn(persistedColumn);
if (dbColumn == null) {
valErrors.Add(
$"Missing column: {persistedColumn.GetColumnName(StoreObjectIdentifier.Table(persistedType.GetTableName(), null))} in {persistedType.GetTableName()}");
continue;
}

var columnTypesMatch =
dbColumn.StoreType.Equals(persistedColumn.GetColumnType(), StringComparison.OrdinalIgnoreCase);
if (!columnTypesMatch) {
valErrors.Add(
$"Column type mismatch in {persistedType.GetTableName()} for column {persistedColumn.GetColumnName(StoreObjectIdentifier.Table(persistedType.GetTableName(), null))}. Found: {dbColumn.StoreType.ToLowerInvariant()}, Expected {persistedColumn.GetColumnType().ToLowerInvariant()}");
if (persistedType.FindAnnotation(RelationalAnnotationNames.TableName)?.Value != null) {
if (dbColumn == null) {
valErrors.Add(
$"Missing column: {persistedColumn.GetColumnName(StoreObjectIdentifier.Table(persistedType.GetTableName(), null))} in {persistedType.GetTableName()}");
continue;
}

var columnTypesMatch =
dbColumn.StoreType.Equals(persistedColumn.GetColumnType(), StringComparison.OrdinalIgnoreCase);
if (!columnTypesMatch) {
valErrors.Add(
$"Column type mismatch in {persistedType.GetTableName()} for column {persistedColumn.GetColumnName(StoreObjectIdentifier.Table(persistedType.GetTableName(), null))}. Found: {dbColumn.StoreType.ToLowerInvariant()}, Expected {persistedColumn.GetColumnType().ToLowerInvariant()}");
}

if (validationOptions.ValidateNullabilityForTables && persistedColumn.IsNullable != dbColumn.IsNullable) {
valErrors.Add(
$"Column nullability mismatch in {persistedType.GetTableName()} for column {persistedColumn.GetColumnName(StoreObjectIdentifier.Table(persistedType.GetTableName(), null))}. Found: {(dbColumn.IsNullable ? "Nullable" : "NotNullable")}, Expected {(persistedColumn.IsNullable ? "Nullable" : "NotNullable")}");
}
}

var isViewType = persistedType.FindAnnotation(RelationalAnnotationNames.ViewDefinitionSql) != null;
var shouldValidateColumnNullability = (validationOptions.ValidateNullabilityForTables && !isViewType) ||
(validationOptions.ValidateNullabilityForViews && isViewType);
if (shouldValidateColumnNullability && persistedColumn.IsNullable != dbColumn.IsNullable) {
valErrors.Add(
$"Column nullability mismatch in {persistedType.GetTableName()} for column {persistedColumn.GetColumnName(StoreObjectIdentifier.Table(persistedType.GetTableName(), null))}. Found: {(dbColumn.IsNullable ? "Nullable" : "NotNullable")}, Expected {(persistedColumn.IsNullable ? "Nullable" : "NotNullable")}");
if (persistedType.FindAnnotation(RelationalAnnotationNames.ViewName)?.Value != null) {
if (dbColumn == null) {
valErrors.Add(
$"Missing column: {persistedColumn.GetColumnName(StoreObjectIdentifier.View(persistedType.GetViewName(), null))} in {persistedType.GetViewName()}");
continue;
}

var columnTypesMatch =
dbColumn.StoreType.Equals(persistedColumn.GetColumnType(), StringComparison.OrdinalIgnoreCase);
if (!columnTypesMatch) {
valErrors.Add(
$"Column type mismatch in {persistedType.GetViewName()} for column {persistedColumn.GetColumnName(StoreObjectIdentifier.View(persistedType.GetViewName(), null))}. Found: {dbColumn.StoreType.ToLowerInvariant()}, Expected {persistedColumn.GetColumnType().ToLowerInvariant()}");
}

if (validationOptions.ValidateNullabilityForViews && persistedColumn.IsNullable != dbColumn.IsNullable) {
valErrors.Add(
$"Column nullability mismatch in {persistedType.GetViewName()} for column {persistedColumn.GetColumnName(StoreObjectIdentifier.View(persistedType.GetViewName(), null))}. Found: {(dbColumn.IsNullable ? "Nullable" : "NotNullable")}, Expected {(persistedColumn.IsNullable ? "Nullable" : "NotNullable")}");
}
}
}

Expand Down
Expand Up @@ -47,7 +47,6 @@
<Compile Include="..\entityframeworkcore2.validation.tests\Support\TableBasedEntity.cs" Link="Support\TableBasedEntity.cs" />
<Compile Include="..\entityframeworkcore2.validation.tests\Support\TableBasedEntityMapping.cs" Link="Support\TableBasedEntityMapping.cs" />
<Compile Include="..\entityframeworkcore2.validation.tests\Support\ViewBasedEntity.cs" Link="Support\ViewBasedEntity.cs" />
<Compile Include="..\entityframeworkcore3.validation.tests\Support\ViewBasedEntityMapping.cs" Link="Support\ViewBasedEntityMapping.cs" />
<Compile Include="..\entityframeworkcore2.validation.tests\Support\XUnit\ConditionalFactAttribute.cs" Link="Support\XUnit\ConditionalFactAttribute.cs" />
<Compile Include="..\entityframeworkcore2.validation.tests\Support\XUnit\ConditionalFactAttributeDiscoverer.cs" Link="Support\XUnit\ConditionalFactAttributeDiscoverer.cs" />
<Compile Include="..\entityframeworkcore2.validation.tests\Support\XUnit\ConditionalFactTestCase.cs" Link="Support\XUnit\ConditionalFactTestCase.cs" />
Expand Down
@@ -0,0 +1,12 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Aranasoft.Cobweb.EntityFrameworkCore.Validation.Tests.Support {
public class ViewBasedEntityMapping : IEntityTypeConfiguration<ViewBasedEntity> {
public void Configure(EntityTypeBuilder<ViewBasedEntity> builder) {
builder.ToView("ViewBasedEntities").ToTable(null);
builder.HasOne(entity => entity.TableEntity).WithMany().HasForeignKey(view => view.Id);
builder.HasOne(entity => entity.Role).WithMany();
}
}
}

0 comments on commit 3d6ff24

Please sign in to comment.