diff --git a/src/EfCore/DKNet.EfCore.Extensions/Configurations/IDataSeedingConfiguration.cs b/src/EfCore/DKNet.EfCore.Extensions/Configurations/IDataSeedingConfiguration.cs
index bab3bf5a..9ad30e94 100644
--- a/src/EfCore/DKNet.EfCore.Extensions/Configurations/IDataSeedingConfiguration.cs
+++ b/src/EfCore/DKNet.EfCore.Extensions/Configurations/IDataSeedingConfiguration.cs
@@ -8,7 +8,7 @@ namespace DKNet.EfCore.Extensions.Configurations;
///
/// Describes a data seeding configuration for an entity type. Implementations may provide a synchronous
-/// list of data via , and/or an asynchronous seeding callback via .
+/// list of data asynchronous seeding callback via .
///
public interface IDataSeedingConfiguration
{
@@ -29,13 +29,6 @@ public interface IDataSeedingConfiguration
///
Func? SeedAsync { get; }
- ///
- /// Model-managed seed data (collection of anonymous/dynamic objects) that will be used by EF Core's model seeding
- /// support.
- /// Implementations may expose strongly typed collections via the generic base class and map them to this property.
- ///
- IEnumerable HasData { get; }
-
///
/// The CLR of the entity that this seeding configuration targets.
///
@@ -46,7 +39,7 @@ public interface IDataSeedingConfiguration
///
/// Generic base class for data seeding configurations. Implementers can provide model-managed seed data via
-/// or an asynchronous seed routine via .
+/// or an asynchronous seed routine via .
///
/// The entity type to seed.
public abstract class DataSeedingConfiguration : IDataSeedingConfiguration where TEntity : class
@@ -56,15 +49,28 @@ public abstract class DataSeedingConfiguration : IDataSeedingConfigurat
///
public Type EntityType => typeof(TEntity);
- ///
- public IEnumerable HasData => GetData();
-
///
public virtual int Order => 0;
-
///
- public virtual Func? SeedAsync => null;
+ public virtual Func SeedAsync =>
+ async (context, isMigration, cancellation) =>
+ {
+ var data = await GetDataAsync(cancellation).ConfigureAwait(false);
+ if (data.Count == 0)
+ return;
+
+ var dbSet = context.Set();
+ foreach (var item in data)
+ {
+ // Check if the item already exists in the database to avoid duplicates
+ var exists = await dbSet.AnyAsync(e => e.Equals(item), cancellation).ConfigureAwait(false);
+ if (!exists)
+ await dbSet.AddAsync(item, cancellation).ConfigureAwait(false);
+ }
+
+ await context.SaveChangesAsync(cancellation).ConfigureAwait(false);
+ };
#endregion
@@ -74,7 +80,7 @@ public abstract class DataSeedingConfiguration : IDataSeedingConfigurat
/// Gets the collection of seed data for the target entity type./>
///
///
- protected abstract ICollection GetData();
+ protected abstract ValueTask> GetDataAsync(CancellationToken cancellation = default);
#endregion
}
\ No newline at end of file
diff --git a/src/EfCore/DKNet.EfCore.Extensions/Extensions/EfCoreDataSeedingExtensions.cs b/src/EfCore/DKNet.EfCore.Extensions/Extensions/EfCoreDataSeedingExtensions.cs
index 197a0344..4063469b 100644
--- a/src/EfCore/DKNet.EfCore.Extensions/Extensions/EfCoreDataSeedingExtensions.cs
+++ b/src/EfCore/DKNet.EfCore.Extensions/Extensions/EfCoreDataSeedingExtensions.cs
@@ -35,33 +35,6 @@ private static Type[] GetDataSeedingTypes(this ICollection? assemblies
return [.. types];
}
- ///
- /// Registers model-managed seed data from discovered types.
- /// This will call HasData on the model for any configuration that exposes non-empty HasData collections.
- ///
- /// The model builder to register seed data on.
- /// Assemblies to scan for IDataSeedingConfiguration implementations.
- internal static void RegisterDataSeeding(this ModelBuilder modelBuilder, params Assembly[] assemblies)
- {
- ArgumentNullException.ThrowIfNull(modelBuilder);
-
- var seedingTypes = assemblies.GetDataSeedingTypes();
- var instances = seedingTypes
- .Select(t => Activator.CreateInstance(t) as IDataSeedingConfiguration)
- .OfType()
- .OrderBy(s => s.Order);
-
- foreach (var item in instances)
- {
- var data = item.HasData?.ToList() ?? [];
- if (data.Count == 0) continue;
-
- var entityType = item.EntityType;
- // ModelBuilder.Entity(Type).HasData accepts params object[]
- modelBuilder.Entity(entityType).HasData(data.ToArray());
- }
- }
-
///
/// Configure the to automatically run data seeding callbacks
/// discovered in the provided assemblies during migrations or startup.
diff --git a/src/EfCore/DKNet.EfCore.Extensions/Internal/AutoConfigModelCustomizer.cs b/src/EfCore/DKNet.EfCore.Extensions/Internal/AutoConfigModelCustomizer.cs
index 600f756b..e922b3a2 100644
--- a/src/EfCore/DKNet.EfCore.Extensions/Internal/AutoConfigModelCustomizer.cs
+++ b/src/EfCore/DKNet.EfCore.Extensions/Internal/AutoConfigModelCustomizer.cs
@@ -14,22 +14,16 @@ private static void ConfigModelCreating(DbContext dbContext, ModelBuilder modelB
var assemblies = GetAssemblies(dbContext);
//Register Entities
- foreach (var assembly in assemblies)
- {
- modelBuilder.ApplyConfigurationsFromAssembly(assembly);
- }
+ foreach (var assembly in assemblies) modelBuilder.ApplyConfigurationsFromAssembly(assembly);
//Register StaticData Of
- modelBuilder.RegisterDataSeeding(assemblies);
+ //modelBuilder.RegisterDataSeeding(assemblies);
//Register Global Filter
modelBuilder.RegisterGlobalModelBuilders(assemblies, dbContext);
//Register Sequence
- if (dbContext.IsSqlServer())
- {
- modelBuilder.RegisterSequences(assemblies);
- }
+ if (dbContext.IsSqlServer()) modelBuilder.RegisterSequences(assemblies);
}
public void Customize(ModelBuilder modelBuilder, DbContext context)
@@ -44,10 +38,7 @@ private static Assembly[] GetAssemblies(DbContext dbContext)
var register = options.FindExtension();
var assemblies = register?.Assemblies ?? [];
- if (assemblies.Length <= 0)
- {
- assemblies = [dbContext.GetType().Assembly];
- }
+ if (assemblies.Length <= 0) assemblies = [dbContext.GetType().Assembly];
return assemblies;
}
diff --git a/src/EfCore/EfCore.Extensions.Tests/DataSeedingTests.cs b/src/EfCore/EfCore.Extensions.Tests/DataSeedingTests.cs
index fe519e59..91f2c7ac 100644
--- a/src/EfCore/EfCore.Extensions.Tests/DataSeedingTests.cs
+++ b/src/EfCore/EfCore.Extensions.Tests/DataSeedingTests.cs
@@ -8,19 +8,20 @@ public class UserSeedingConfiguration : DataSeedingConfiguration
{
#region Methods
- protected override ICollection GetData() =>
- [
- new(
- 1, "seeded1")
- {
- FirstName = "Seeded", LastName = "User1"
- },
- new(2, "seeded2")
- {
- FirstName = "Seeded",
- LastName = "User2"
- }
- ];
+ protected override ValueTask> GetDataAsync(CancellationToken cancellationToken = default) =>
+ ValueTask.FromResult>(
+ [
+ new User(
+ 1, "seeded1")
+ {
+ FirstName = "Seeded", LastName = "User1"
+ },
+ new User(2, "seeded2")
+ {
+ FirstName = "Seeded",
+ LastName = "User2"
+ }
+ ]);
#endregion
}