Key in table becomes Guid.Empty entityframework core - c#

I have the following entities:
public class ElectedRepresentativeData : TimeTrackBase
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public int CustomerNumber { get; set; }
public int RegionId { get; set; }
public bool Success { get; set; }
public virtual Accountants Accountants { get; set; }
}
public class Accountants : TimeTrackBase
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public Guid ElectedRepresentativeDataId { get; set; }
public virtual Accountant Accountant { get; set; }
public virtual AccountantSubstitute AccountantSubstitute { get; set; }
}
public class Accountant : TimeTrackBase
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public Guid AccountantsId { get; set; }
public virtual Person AccountantPerson { get; set; }
}
public class AccountantSubstitute : TimeTrackBase
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public Guid AccountantsId { get; set; }
public virtual Person AccountantPerson { get; set; }
}
The problem I have is that the AccountantsId becomes Guid.Empty(00000000-0000-0000-0000-000000000000) in the table AccountantSubstitute, while the AccountantsId in the table Accountant works as expected.
Should it not work in the AccountantSubstitute as well?

You must create a configuration class and configure properties in more detail.
public class AccountantConfiguration : IEntityTypeConfiguration<Accountant>
{
/// <inheritdoc />
public void Configure(EntityTypeBuilder<Communication> builder)
{
if (builder == null)
return;
builder.ToTable("Accountant");
builder.HasKey(k => new {Id = k.Id});
builder.Property(p => p.Id)
.IsRequired();
builder.Property(p => p.AccountantsId)
.IsRequired()
.HasDefaultValueSql("newid()")
.ValueGeneratedOnAdd();
...
}
}
And add this configuration in DbContext class
public sealed class Context : DbContext
{
...
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
if (builder == null)
return;
builder.ApplyConfiguration(new AccountantConfiguration());
}
}

Related

how to add 2 foreign keys in a new table using entity framework core

I am trying to make a table that has 2 foreign keys referencing two other tables,
what I have is an ItemTable and an OrderTable , I want to take the primary key of both tables and put them in OrderDetials table using asp.net EF core.
here is my itemTable.cs Model :
public class ItemTables
{
[Key]
public int Id { get; set; }
public string company { get; set; }
public string availability { get; set; }
public decimal price { get; set; }
public decimal discount { get; set; }
public decimal tax { get; set; }
public string description { get; set; }
public int categoryid { get; set; }
public categories categories { get; set; }
//public ICollection<OrderDetials> ItemDetials { get; set; }
}
public class categories
{
[Key]
public int categoryID { get; set; }
public string categoryName { get; set; }
public ICollection<ItemTables> items { get; set; }
}
and here is my Dbcontext for itemtables :
public class itemTableDbContext : DbContext
{
public itemTableDbContext(DbContextOptions<itemTableDbContext> options) : base(options)
{
}
public DbSet<ItemTables>? ItemTables { get; set; }
public DbSet<categories>? categories { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ItemTables>()
.HasOne<categories>(c => c.categories)
.WithMany(i => i.items)
.HasForeignKey(f => f.categoryid);
}
}
OrderTable.cs model :
public class OrderTable
{
[Key]
public int Id { get; set; }
public string OperationType { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime Date { get; set; }
public string Address { get; set; }
public string Custname { get; set; }
public int NetTotal { get; set; }
public int GrossTotal { get; set; }
public int DiscountTotal { get; set; }
public int TaxTotal { get; set; }
public int QuantityTotal { get; set; }
public int UserID { get; set; }
public Users User { get; set; }
//public ICollection<OrderDetials> orderDetials { get; set; }
}
and its Dbcontext for the ordertable :
public class usersANDordersDbContext : DbContext
{
public usersANDordersDbContext(DbContextOptions options) : base(options)
{
}
public DbSet<Users> Users { get; set; }
public DbSet<OrderTable> orders { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<OrderTable>()
.HasOne<Users>(u => u.User)
.WithMany(o => o.orders)
.HasForeignKey(f => f.UserID);
modelBuilder.Entity<OrderTable>().ToTable("OrderTable");
modelBuilder.Entity<Users>().ToTable("Users");
}
}
and here is my attempt at the OrderDetials table Model :
[Keyless]
public class OrderDetials
{
public int OrderID { get; set; }
public OrderTable OrderTable { get; set; }
public int ItemID { get; set; }
public ItemTables itemTables { get; set; }
public int Quantity { get; set; }
public int GrossTotal { get; set; }
public int DiscountAmount { get; set; }
public int TaxAmount { get; set; }
public int Total { get; set; }
}
and its DbContext for the orderDetials :
public class OrderDetialsDbContext : DbContext
{
//public OrderDetialsDbContext(DbContextOptions options) : base(options)
//{
//}
//public Microsoft.EntityFrameworkCore.DbSet<OrderDetials> OrderDetials { get; set; }
//protected override void OnModelCreating(ModelBuilder modelBuilder)
//{
// modelBuilder.Entity<OrderDetials>()
// .HasOne<OrderTable>(o => o.OrderTable)
// .WithMany(d => d.orderDetials).HasForeignKey(f => f.OrderID);
// modelBuilder.Entity<OrderDetials>()
// .HasOne<ItemTables>(o => o.itemTables)
// .WithMany(d => d.ItemDetials).HasForeignKey(f => f.ItemID);
// modelBuilder.Entity<OrderDetials>().ToTable("OrderDetials");
//}
}
I tried implementing it, but the migration gave me an error, I assume it has to do with how I am defining my model and DbContext, I am new to asp.net and EF core, if any information needed just let me know , and thanks in advance .
the migration error :
Add-Migration : A parameter cannot be found that matches parameter name 'Context'.
At line:1 char:23
+ Add-Migration detials -Context OrderDetialsDbContext
+ ~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Add-Migration], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Add-Migration

EF Core - many to many with another foreign key

I need to create this tables:
Step (ID, Name)
Action (ID, Name)
StepActions(IdStep, IdAction, NextStep)
In Entity Framework:
public class Step
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<StepActions> StepActions { get; set; }
}
public class Action
{
public int Id { get; set; }
public virtual ICollection<StepActions> StepActions{ get; set; }
}
public class StepActions
{​​​​​​​
public virtual Action Action {​​​​​​​ get; set; }​​​​​​​
public virtual Step Step {​​​​​​​ get; set; }​​​​​​​
public int Id {​​​​​​​ get; set; }​​​​​​​
public int ActionID {​​​​​​​ get; set; }​​​​​​​
public int StepID {​​​​​​​ get; set; }​​​​​​​
public int NextStepID {​​​​​​​ get; set; }​​​​​​​
}​​​​​​​​​​​​​​
I can create many-to-many relationship, but I don't know how to add relatioship for NextStep.
Thanks
Use these classes:
public partial class Step
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
[InverseProperty(nameof(StepAction.NexStep))]
public virtual ICollection<StepAction> StepActionNexSteps { get; set; }
[InverseProperty(nameof(StepAction.Step))]
public virtual ICollection<StepAction> StepActionSteps { get; set; }
}
public partial class Action
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
[InverseProperty(nameof(StepAction.Action))]
public virtual ICollection<StepAction> StepActions { get; set; }
}
public partial class StepAction
{
[Key]
public int Id { get; set; }
public int StepId { get; set; }
public int ActionId { get; set; }
public int NexStepId { get; set; }
[ForeignKey(nameof(StepId))]
[InverseProperty("StepActionSteps")]
public virtual Step Step { get; set; }
[ForeignKey(nameof(ActionId))]
[InverseProperty("StepActions")]
public virtual Action Action { get; set; }
[ForeignKey(nameof(NexStepId))]
[InverseProperty("StepActionNexSteps")]
public virtual Step NexStep { get; set; }
}
and this dbcontext:
public partial class StepsContext : DbContext
{
public StepsContext()
{
}
public StepsContext(DbContextOptions<StepsContext> options)
: base(options)
{
}
public virtual DbSet<Action> Actions { get; set; }
public virtual DbSet<Step> Steps { get; set; }
public virtual DbSet<StepAction> StepActions { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<StepAction>(entity =>
{
entity.HasOne(d => d.Action)
.WithMany(p => p.StepActions)
.HasForeignKey(d => d.ActionId)
.OnDelete(DeleteBehavior.ClientSetNull);
entity.HasOne(d => d.NexStep)
.WithMany(p => p.StepActionNexSteps)
.HasForeignKey(d => d.NexStepId)
.OnDelete(DeleteBehavior.ClientSetNull);
entity.HasOne(d => d.Step)
.WithMany(p => p.StepActionSteps)
.HasForeignKey(d => d.StepId)
.OnDelete(DeleteBehavior.ClientSetNull);
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}

EF-Model for many-to-many Junction Table

I'm trying to straighten out the EF-Model for a junctiontable OwnerCows.dbo.
There's a class Cow with an Id, a class Owner with an Id and i want to reference them both in a OwnerCows-table that has only an OwnerCowId, a CowId(FK) and a OwnerId(FK).
The error I'm getting is:
Cannot create a relationship between 'Owner.OwnerCows' and 'OwnerCow.Owner', because there already is a relationship between 'Owner.CowOwners' and 'OwnerCow.Owner'. Navigation properties can only participate in a single relationship.
Does it mean I have a circular reference? How can I solve this?
the Owner.cs:
public class Owner : EntityBase<Guid>
{
public string Name { get; set; }
[NotMapped]
public ICollection<Cow> Cows { get; set; }
= new List<Cow>();
public virtual List<OwnerCow> CowOwners { get; set; }
public Cow Cow { get; set; }
}
the Cow.cs:
public class Cow : EntityBase<Guid>
{
[MaxLength(50)]
public string Name { get; set; }
public string Breed { get; set; }
public string Color { get; set; }
public ICollection<Entities.Weight> Weights { get; set; }
= new List<Weight>();
public ICollection<Vaccination> Vaccinations { get; set; }
= new List<Vaccination>();
[NotMapped]
public ICollection<Owner> CowOwners { get; set; }
= new List<Owner>();
public List<OwnerCow> OwnerCows { get; set; }
}
the OwnerCows.cs:
public class OwnerCow
{
public Guid OwnerCowId { get; set; }
public Cow Cow { get; set; }
public Guid CowId { get; set; }
public Owner Owner { get; set; }
public Guid OwnerId { get; set; }
}
the Context-class:
public class DogFaceContext : DbContext
{
public DogFaceContext()
{
}
public DogFaceContext(DbContextOptions<DogFaceContext> options)
: base(options)
{
Database.Migrate();
}
//Entity Tables
public virtual DbSet<Owner> Owners { get; set; }
public virtual DbSet<Cow> Cows { get; set; }
public virtual DbSet<Vaccination> Vaccination { get; set; }
public virtual DbSet<Weight> Weight { get; set; }
//Junction Tables
public virtual DbSet<OwnerCow> OwnerCows { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Cow>().HasMany(x => x.CowOwners).WithOne(x => x.Cow);
builder.Entity<Owner>().HasMany(u => u.CowOwners).WithOne(X => X.Owner);
builder.Entity("DogFace.API.Entities.OwnerCow", b =>
{
b.HasOne("DogFace.API.Entities.Cow", "Cow")
.WithMany("OwnerCows")
.HasForeignKey("CowId")
.OnDelete(DeleteBehavior.Restrict);
b.HasOne("DogFace.API.Entities.Owner", "Owner")
.WithMany("OwnerCows")
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Restrict);
});
}
}
Can I get it to work with this design? Is it possible with EFCore? Any other suggestions? Thanks!
You model is very complex and has some unnecessary relationships like Owner.Cows since you decide to configure many-to-many relationship.You could just get Owner's cows using
var owner = new Owner();
List<Cow> cows = owner.OwnerCows.Where(oc => oc.OwnerId == owner.Id)
.Select(oc => oc.Cow)
.ToList();
1.To have OwnerCowId, a CowId(FK) and a OwnerId(FK) in OwnerCows, refer to my below configuration:
public class Owner : EntityBase<Guid>
{
public string Name { get; set; }
public virtual List<OwnerCow> OwnerCows { get; set; }
}
public class Cow : EntityBase<Guid>
{
[MaxLength(50)]
public string Name { get; set; }
public string Breed { get; set; }
public string Color { get; set; }
public ICollection<Entities.Weight> Weights { get; set; } = new List<Weight>();
public ICollection<Vaccination> Vaccinations { get; set; }= new List<Vaccination>();
public List<OwnerCow> OwnerCows { get; set; }
}
public class OwnerCow
{
[Key]
public Guid OwnerCowId { get; set; }
public Cow Cow { get; set; }
public Guid CowId { get; set; }
public Owner Owner { get; set; }
public Guid OwnerId { get; set; }
}
DbContext:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<OwnerCow>()
.HasOne(oc => oc.Cow)
.WithMany(c => c.OwnerCows)
.HasForeignKey(oc => oc.CowId);
builder.Entity<OwnerCow>()
.HasOne(oc => oc.Owner)
.WithMany(o => o.OwnerCows)
.HasForeignKey(oc => oc.OwnerId);
}
}
In this case, your OwnerCowId id the primary key for your OwnerCows table which is not reasonable and it may have the same record of CowId,OwnerId for OwnerCows.
2.Usually,the primary key for the join table is a composite key comprising both of the foreign key values,I suggest that you could use composite key for your OwnerCow:
public class OwnerCow
{
public Cow Cow { get; set; }
public Guid CowId { get; set; }
public Owner Owner { get; set; }
public Guid OwnerId { get; set; }
}
DbContext:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<OwnerCow>()
.HasKey(oc => new { oc.OwnerId, oc.CowId });
builder.Entity<OwnerCow>()
.HasOne(oc => oc.Cow)
.WithMany(c => c.OwnerCows)
.HasForeignKey(oc => oc.CowId);
builder.Entity<OwnerCow>()
.HasOne(oc => oc.Owner)
.WithMany(o => o.OwnerCows)
.HasForeignKey(oc => oc.OwnerId);
}
}
Refer to https://www.learnentityframeworkcore.com/configuration/many-to-many-relationship-configuration
Fix context builder:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Cow>().HasMany(x => x.CowOwners).WithOne(x => x.Cow);
builder.Entity<Owner>().HasMany(u => u.Cows).WithOne(X => X.Owner); // Cows instead of CowOwners
builder.Entity("DogFace.API.Entities.OwnerCow", b =>
{
b.HasOne("DogFace.API.Entities.Cow", "Cow")
.WithMany("OwnerCows")
.HasForeignKey("CowId")
.OnDelete(DeleteBehavior.Restrict);
b.HasOne("DogFace.API.Entities.Owner", "Owner")
.WithMany("CowOwners") // CowOwners instead of OwnerCows
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Restrict);
});
}
... or fix property names in classes:
public class Owner : EntityBase<Guid>
{
public string Name { get; set; }
[NotMapped]
public ICollection<Cow> CowOwners { get; set; } // CowOwners instead of Cows ?
= new List<Cow>();
public virtual List<OwnerCow> OwnerCow { get; set; } // OwnerCow instead of CowOwners ?
public Cow Cow { get; set; }
}
but don't forget to change dbcontext builder with fixed property names.

EF Populate Navigation Property on Id match

I am trying to populate a List<Dock> when Profile.MatchId == Dock.MatchId from different classes.
This is a stripped down version of both classes:
public class Profile
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ProfileId { get; set; }
public int MatchId { get; set; }
public virtual List<Dock> Docks { get; set; } = new List<Dock>();
}
public class Dock
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int DockId { get; set; }
public int MatchId { get; set; }
}
How do I get the List<Dock> Docks navigation properties to correctly populate? I am believe I need to wire this up via modelBuilder - however have not done this before.
Good Time! There's a pretty simple example of model relationship configuration.
public class SomeContext : DbContext
{
public DbSet<Profile> Profiles { get; set; }
public DbSet<Dock> Docks { get; set; }
protected override Void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Dock>()
.HasOne(x => x.Profile)
.WithMany(x => x.Docks)
.HasForeignKey(x => x.ProfileId);
}
}
public class Profile
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ProfileId { get; set; }
public int MatchId { get; set; }
public virtual List<Dock> Docks { get; set; } = new List<Dock>();
}
public class Dock
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int DockId { get; set; }
public int MatchId { get; set; }
public int ProfileId { get; set; }
public Profile Profile { get; set; }
}
Actually you can't get values for List<> Docks in Profile, as you don't have direct connection between Profile and Docks.
You may try with this.
public class Profile
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ProfileId { get; set; }
public virtual List<Dock> Docks { get; set; } = new List<Dock>();
}
public class Dock
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int DockId { get; set; }
[ForeignKey("Profile")]
public int ProfileId { get; set; }
public Profile Profile {get; set; }
}

EF Core Relation doesn't exist

I want to create a database in PostgreSQL and API for my app. I've created Model and API in EF Core 1.0.0. Model exists in separate library.
public class Architect : IEntity
{
public Guid Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string PhoneNumber { get; set; }
public string Email { get; set; }
public ICollection<Project> Projects { get; set; }
}
public class Project : IEntity
{
public Guid Id { get; set; }
public string Name { get; set; }
[JsonConverter(typeof(IsoDateTimeConverter))]
public DateTimeOffset CreatedAt { get; set; }
public ICollection<Company> Companies { get; set; }
public string City { get; set; }
public ICollection<ProjectState> ProjectStates { get; set; }
public Guid ArchitectId { get; set; }
public Architect Architect { get; set; }
}
public class Company : IEntity
{
public Guid Id { get; set; }
public string Name { get; set; }
public Guid ProjectId { get; set; }
public Project Project { get; set; }
}
public class ProjectState : IEntity
{
public Guid Id { get; set; }
public ProjectPhase phase { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public Guid ProjectId { get; set; }
public Project Project { get; set; }
}
I have created also DemoContext that inherits DbContext. I defined relashionships in OnModelCreating(ModelBuilder modelBuilder) method.
public class DemoContext : DbContext
{
public DbSet<Architect> Architects { get; set; }
public DbSet<Project> Projects { get; set; }
public DbSet<Company> Companies { get; set; }
public DbSet<ProjectState> ProjectStates { get; set; }
public DemoContext(DbContextOptions<DemoContext> options) : base(options) { }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseNpgsql("PORT = 5432; HOST = localhost; TIMEOUT = 15; POOLING = True; MINPOOLSIZE = 1; MAXPOOLSIZE = 20; COMMANDTIMEOUT = 20; DATABASE = ProgressTest; PASSWORD = 'postgres'; USER ID = postgres", b => b.MigrationsAssembly("WebAPI.API"));
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasPostgresExtension("uuid-ossp");
modelBuilder.Entity<Project>()
.HasOne(p => p.Architect)
.WithMany(a => a.Projects)
.HasForeignKey(p=>p.ArchitectId);
modelBuilder.Entity<ProjectState>()
.HasOne(p => p.Project)
.WithMany(p => p.ProjectStates)
.HasForeignKey(p => p.ProjectId);
modelBuilder.Entity<Company>()
.HasOne(c => c.Project)
.WithMany(p => p.Companies)
.HasForeignKey(c => c.ProjectId);
}
}
I want to migrate all classes and create new database. I've used
dotnet ef migrations add InitializeMigration to add new migration and after it I wanted to update my database, so I've used dotnet ef database update but Postgres throw an Exception:
Npgsql.PostgresException: 42P01: relationship "ProjectState.IX_ProjectState_ProjectId" doesn't exist
Can you help me with it?
In my case i just decorate my model class with "Table" attribute with actual table name (mind case sensativity) and it resolved my problem
[Table("city")]
public class CityModel

Categories

Resources