How to seed in navigation property?

entity-framework-core

Question

I have several models in this Db,

I am using the following seeding class, and I initialize it at startup using SeedData.Initialize(serviceProvider);where serviceProvider is injected in the Configure method.

public class SeedData
    {
        public static void Initialize(IServiceProvider serviceProvider)
        {
            using (var context = new ArtCoreDbContext(
                serviceProvider.GetRequiredService<DbContextOptions<ArtCoreDbContext>>()))
            {
                // Look for any movies.
                if (context.Genders.Any())
                {
                    return;   // DB has been seeded
                }

                context.Genders.AddRange(
                     new Genders
                     {
                         Name = "Male"
                     },

                     new Genders
                     {
                         Name = "Female"
                     }

                );
                context.SaveChanges();

                if (context.Statuses.Any())
                {
                    return;   // DB has been seeded
                }

                context.Statuses.AddRange(
                     new Statuses
                     {
                         Name = "Active"
                     },

                     new Statuses
                     {
                         Name = "Inactive"
                     },

                     new Statuses
                     {
                         Name = "Cancelled"
                     }


                );
                context.SaveChanges();

                if (context.PatientsRegistry.Any())
                {
                    return;   // DB has been seeded
                }

                context.PatientsRegistry.AddRange(
                     new PatientsRegistry
                     {
                        PatientFileId = 1234,
                        FirstName = "John",
                        SecondName = "M",
                        LastName = "Doe",
                        Gender = {Id = 5, Name="Male"},
                        Status = {Id = 2, Name="Inactive"}
                     }
                );
                context.SaveChanges();

            }
        }
    }

and their models are

public class Genders
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

public class Statuses
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }


[Table("PatientsRegistry")]
    public class PatientsRegistry
    {   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public long RecordId { get; set; }
        [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
        public long PatientFileId { get; set; }
        public string FirstName { get; set; }
        public string SecondName { get; set; }
        public string LastName { get; set; }
        public Genders Gender { get; set; }
        public Statuses Status { get; set; }
        public ICollection<PartnersRegistry> Partners { get; set; }

        public PatientsRegistry()
        {
            Partners = new Collection<PartnersRegistry>();
        }

    }

I Succeded in seeding both models (Genders & Statuses) but not PatientsRegistry!, is it the nav. prop?

what am I missing here?

1
0
11/22/2017 10:09:24 AM

Accepted Answer

this is the solution, Ref is here, Answered by Edward Z

 context.PatientsRegistry.AddRange(
           new PatientsRegistry
                     {
                         PatientFileId = 1234,
                         FirstName = "John",
                         SecondName = "M",
                         LastName = "Doe",                        
                         Gender = context.Genders.Where(g => g.Name == "Male").FirstOrDefault(),
                         Status = context.Statuses.Where(s => s.Name == "Inactive").FirstOrDefault()
                     }
                );

Another solution is by adding two new prop to PatientsRegistry along with the Navigation Prop

public int GenderId { get; set; }
public int StatusId { get; set; }

public class Genders
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

public class Statuses
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

[Table("PatientsRegistry")]
    public class PatientsRegistry
    {   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public long RecordId { get; set; }
        [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
        public long PatientFileId { get; set; }
        public string FirstName { get; set; }
        public string SecondName { get; set; }
        public string LastName { get; set; }
        public int GenderId { get; set; }
        public Genders Gender { get; set; }
        public int StatusId { get; set; }
        public Statuses Status { get; set; }
        public ICollection<PartnersRegistry> Partners { get; set; }

        public PatientsRegistry()
        {
            Partners = new Collection<PartnersRegistry>();
        }

    }

Now based on this model the fluent API will create a foreign key with a Cascade RI on Delete which sql server does not accept so I change it to onDelete: ReferentialAction.Restrict);

Now in my seeding class, I can select the Id value as follows (I modified it a bit),

 if (!context.PatientsRegistry.Any())
                {
                    context.PatientsRegistry.AddRange(
                     new PatientsRegistry
                     {
                        PatientFileId = 1234,
                        FirstName = "John",
                        SecondName = "M",
                        LastName = "Doe",
                        GenderId = 1,
                        StatusId = 2
                     }
                );
                context.SaveChanges();
                }
0
11/24/2017 9:18:40 AM

Popular Answer

Add PatientsRegistry to Genders and Statuses:

public class Genders
{
    public int Id { get; set; }

    public string Name { get; set; }

    public ICollection<PatientsRegistry> PatientsRegistries { get; set; }
}

public class Statuses
{
    public int Id { get; set; }

    public string Name { get; set; }

    public ICollection<PatientsRegistry> PatientsRegistries { get; set; }
}

then inside method OnModelCreating in ArtCoreDbContext class add following configs:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Genders>().HasMany(g => g.PatientsRegistries).WithOne(p => p.Gender);
    modelBuilder.Entity<Statuses>().HasMany(g => g.PatientsRegistries).WithOne(p => p.Status);

    base.OnModelCreating(modelBuilder);
}

change you seed class to:

public class SeedData
{
    public static void Initialize(IServiceProvider serviceProvider)
    {
        using(var context = new ArtCoreDbContext(serviceProvider.GetRequiredService<DbContextOptions<ArtCoreDbContext>>())))
        {
            if (context.Genders.Any() && context.Statuses.Any() && context.PatientsRegistries.Any())
                return; // DB has been seeded

            var g1 = new Genders { Name = "Male" };
            var g2 = new Genders { Name = "Female" };
            context.Genders.AddRange(new[] { g1, g2 });

            var s1 = new Statuses { Name = "Active" };
            var s2 = new Statuses { Name = "Inactive" };
            var s3 = new Statuses { Name = "Canceled" };
            context.Statuses.AddRange(new[] { s1, s2, s3 });

            context.PatientsRegistries.AddRange(
                new PatientsRegistry
                {
                    PatientFileId = 1234,
                    FirstName = "John",
                    SecondName = "M",
                    LastName = "Doe",
                    Gender = g1,
                    Status = s1
                },
                new PatientsRegistry
                {
                    PatientFileId = 1235,
                    FirstName = "Julia",
                    SecondName = "M",
                    LastName = "Doe",
                    Gender = g2,
                    Status = s2
                }
            );

            context.SaveChanges();
        }
    }
}


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow