Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't hard-code value generation to Never for FKs #25992

Merged
merged 1 commit into from
Sep 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ public override ConventionSet CreateConventionSet()
ValueGenerationConvention valueGenerationConvention =
new RelationalValueGenerationConvention(Dependencies, RelationalDependencies);
ReplaceConvention(conventionSet.EntityTypeBaseTypeChangedConventions, valueGenerationConvention);
ReplaceConvention(conventionSet.ForeignKeyPropertiesChangedConventions, valueGenerationConvention);
ReplaceConvention(conventionSet.ForeignKeyOwnershipChangedConventions, valueGenerationConvention);
ajcvickers marked this conversation as resolved.
Show resolved Hide resolved
conventionSet.EntityTypeBaseTypeChangedConventions.Add(tableNameFromDbSetConvention);
conventionSet.EntityTypeBaseTypeChangedConventions.Add(new CheckConstraintConvention(Dependencies, RelationalDependencies));

Expand Down
4 changes: 2 additions & 2 deletions src/EFCore/Metadata/Conventions/ValueGenerationConvention.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public virtual void ProcessForeignKeyAdded(
{
foreach (var property in foreignKey.Properties)
{
property.Builder.ValueGenerated(ValueGenerated.Never);
property.Builder.ValueGenerated(GetValueGenerated(property));
}
}
}
Expand Down Expand Up @@ -94,7 +94,7 @@ public virtual void ProcessForeignKeyPropertiesChanged(
{
foreach (var property in foreignKey.Properties)
{
property.Builder.ValueGenerated(ValueGenerated.Never);
property.Builder.ValueGenerated(GetValueGenerated(property));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ public GraphUpdatesInMemoryTest(InMemoryFixture fixture)
{
}

// In-memory database does not have database default values
public override Task Can_insert_when_FK_has_default_value(bool async)
=> Task.CompletedTask;

public override void Required_many_to_one_dependents_are_cascade_deleted_in_store(
CascadeTiming? cascadeDeleteTiming,
CascadeTiming? deleteOrphansTiming)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3451,6 +3451,49 @@ public int CityId
}
}

protected class Cruiser : NotifyingEntity
{
private int _cruiserId;
private int _idUserState;
private AccessState _userState;

public int CruiserId
{
get => _cruiserId;
set => SetWithNotify(value, ref _cruiserId);
}

public int IdUserState
{
get => _idUserState;
set => SetWithNotify(value, ref _idUserState);
}

public virtual AccessState UserState
{
get => _userState;
set => SetWithNotify(value, ref _userState);
}
}

protected class AccessState : NotifyingEntity
{
private int _accessStateId;
private ICollection<Cruiser> _users = new ObservableHashSet<Cruiser>();

public int AccessStateId
{
get => _accessStateId;
set => SetWithNotify(value, ref _accessStateId);
}

public virtual ICollection<Cruiser> Users
{
get => _users;
set => SetWithNotify(value, ref _users);
}
}

protected class NotifyingEntity : INotifyPropertyChanging, INotifyPropertyChanged
{
protected void SetWithNotify<T>(T value, ref T field, [CallerMemberName] string propertyName = "")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,33 @@ namespace Microsoft.EntityFrameworkCore
public abstract partial class GraphUpdatesTestBase<TFixture>
where TFixture : GraphUpdatesTestBase<TFixture>.GraphUpdatesFixtureBase, new()
{
[ConditionalTheory] // Issue #23974
[InlineData(false)]
[InlineData(true)]
public virtual async Task Can_insert_when_FK_has_default_value(bool async)
{
await ExecuteWithStrategyInTransactionAsync(
async context =>
{
if (async)
{
await context.AddAsync(new Cruiser());
await context.SaveChangesAsync();
}
else
{
context.Add(new Cruiser());
context.SaveChanges();
}
},
async context =>
{
var queryable = context.Set<Cruiser>().Include(e => e.UserState);
var cruiser = async ? (await queryable.SingleAsync()) : queryable.Single();
Assert.Equal(cruiser.IdUserState, cruiser.UserState.AccessStateId);
});
}

[ConditionalTheory] // Issue #23043
[InlineData(false)]
[InlineData(true)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,20 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con
});

modelBuilder.Entity<City>();

modelBuilder.Entity<AccessState>(
b =>
{
b.Property(e => e.AccessStateId).ValueGeneratedNever();
b.HasData(new AccessState {AccessStateId = 1});
});

modelBuilder.Entity<Cruiser>(
b =>
{
b.Property(e => e.IdUserState).HasDefaultValue(1);
b.HasOne(e => e.UserState).WithMany(e => e.Users).HasForeignKey(e => e.IdUserState);
});
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,25 @@ public TestSqlLoggerFactory TestSqlLoggerFactory

protected override ITestStoreFactory TestStoreFactory
=> SqlServerTestStoreFactory.Instance;

protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context)
{
base.OnModelCreating(modelBuilder, context);

modelBuilder.Entity<AccessState>(
b =>
{
b.Property(e => e.AccessStateId).ValueGeneratedNever();
b.HasData(new AccessState {AccessStateId = 1});
});

modelBuilder.Entity<Cruiser>(
b =>
{
b.Property(e => e.IdUserState).HasDefaultValue(1);
b.HasOne(e => e.UserState).WithMany(e => e.Users).HasForeignKey(e => e.IdUserState);
});
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,25 @@ public override PoolableDbContext CreateContext()

return context;
}

protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context)
{
base.OnModelCreating(modelBuilder, context);

modelBuilder.Entity<AccessState>(
b =>
{
b.Property(e => e.AccessStateId).ValueGeneratedNever();
b.HasData(new AccessState {AccessStateId = 1});
});

modelBuilder.Entity<Cruiser>(
b =>
{
b.Property(e => e.IdUserState).HasDefaultValue(1);
b.HasOne(e => e.UserState).WithMany(e => e.Users).HasForeignKey(e => e.IdUserState);
});
}
}
}
}