I'am using EF6 and code firt in project, but i get this error on creating the model
Name: Each property name in a type must be unique. Property name 'varchar' is already defined.
below is my entity and my map
public class Menu
{
public Menu()
{
ListaFilhos = new List<Menu>();
}
public Int32 MenuID { get; set; }
public String Nome { get; set; }
public String Action { get; set; }
public String Controller { get; set; }
public String Url { get; set; }
public Int32? Pai { get; set; }
public Boolean? Ativo { get; set; }
public virtual List<Menu> ListaFilhos { get; set; }
}
Map
public class MenuMap : EntityTypeConfiguration<Entidade.Menu>
{
public MenuMap()
{
HasKey(x => x.MenuID);
Property(x => x.MenuID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(x => x.Pai).IsRequired();
Property(x => x.Nome).HasColumnType("varchar").HasMaxLength(100).IsRequired();
Property(x => x.Url).HasColumnName("varchar").HasMaxLength(250);
Property(x => x.Action).HasColumnName("varchar").HasMaxLength(50);
Property(x => x.Controller).HasColumnName("varchar").HasMaxLength(50);
Property(x => x.Ativo).IsRequired();
ToTable("Menu");
}
}
public class MenuGrupo
{
public MenuGrupo()
{
ListaMenu = new List<Menu>();
}
public Int32 MenuGrupoID { get; set; }
public Int32 MenuID { get; set; }
public virtual List<Menu> ListaMenu { get; set; }
}
public class MenuGrupoMap : EntityTypeConfiguration<Entidade.MenuGrupo>
{
public MenuGrupoMap()
{
HasKey(x => x.MenuGrupoID);
Property(x => x.MenuGrupoID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(x => x.MenuID).IsRequired();
ToTable("MenuGrupo");
}
}
I guess my problem is on MenuMap, when i remove in the OnModelCreate, all orther map working.
What i'am doing wrong?
tks
Related
I successfully built migrations, and I am now trying to update the database with my models in Asp.net core but it keeps giving me this error
"The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Posts_Authors_AuthorId". The conflict occurred in database "MediumDb", table "dbo.Authors", column 'AuthorId'.
The statement has been terminated."
This is what the code in my Post class looks like
namespace Medium.Api.Entities
{
public class Post
{
public Guid Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int NoOfClaps { get; set; }
public DateTime CreatedDate { get; set; }
public IQueryable<Tag> Tags { get; set; }
public IQueryable<PostTag> PostTags { get; set; }
public string Image { get; set; }
// public string Video { get; set; }
public Author Author { get; set; }
public int AuthorId { get; set; }
while the code in my Author class says this
namespace Medium.Api.Entities
{
public class Author
{
public int AuthorId { get; set; }
public string Name { get; set; }
public IQueryable<Post> Posts { get; set; }
}
}
This is my DbContext configuration
{
public class MediumApiContext : DbContext
{
public MediumApiContext(DbContextOptions options)
: base(options)
{
// Database.EnsureCreated();
}
public DbSet<Post> Posts { get; set; }
public DbSet<Author> Authors { get; set; }
public DbSet<Tag> Tags { get; set; }
public DbSet<PostTag> PostTags { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Author>()
.HasKey(a => a.AuthorId);
modelBuilder.Entity<Author>()
.HasMany(a => a.Posts)
.WithOne(p => p.Author);
modelBuilder.Entity<Post>()
.ToTable("Posts");
modelBuilder.Entity<Post>()
.HasKey(p => p.Id);
modelBuilder.Entity<Post>()
.HasOne(p => p.Author)
.WithMany(a => a.Posts);
modelBuilder.Entity<Post>()
.Property(p => p.CreatedDate)
.IsRequired()
.HasColumnType("Date")
.HasDefaultValueSql("getutcdate()");
modelBuilder.Entity<Post>()
.Property(p => p.Title)
.IsRequired();
modelBuilder.Entity<Post>()
.Property(p => p.NoOfClaps)
.IsRequired();
modelBuilder.Entity<Post>()
.Property(p => p.Content)
.IsRequired();
I don't know where I seem to be getting it all wrong. Please
We Use FK for data integrity right now you have FOREIGN KEY with Author Table so :
"The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Posts_Authors_AuthorId". The conflict occurred in database "MediumDb", table "dbo.Authors", column 'AuthorId'. The statement has been terminated."
This means that when you create a Post, you must give an Author_ID that is on the Author table
I want to change a foreign key on my table from not nullable to nullable
Class name : DestinatairePartageDocument
public class DestinatairePartageDocument
{
[Key]
public int DestinatairePartageDocumentId { get; set; }
//[ForeignKey("Document")]
//public int DocumentId { get; set; }
[ForeignKey("Document")]
public int? DocumentId { get; set; }
public Document Document { get; set; }
//[ForeignKey("Examen")]
[NotMapped]
public int? ExamenId { get; set; }
//public Examen Examen { get; set; }
[ForeignKey("DestinatairePartage")]
public int DestinatairePartageId { get; set; }
public DestinatairePartage DestinatairePartage { get; set; }
public string CodeAccesDocument { get; set; }
public DateTime DateFinValiditeCodeAccesDocument { get; set; }
public string TypePartage { get; set; } /* PartageClassique, PartageCodeGenere */
public string StatutDocument { get; set; }
public bool PartageActive { get; set; }
public DateTime DateCreation { get; set; }
public DateTime DateDerniereModification { get; set; }
}
Old property setup :
[ForeignKey("Document")]
public int DocumentId { get; set; }
public Document Document { get; set; }
New property setup :
[ForeignKey("Document")]
public int? DocumentId { get; set; }
public Document Document { get; set; }
Upon doing this update, I then update my migration schema :
dotnet ef Migrations add UpdateDocumentNullable
And then I apply the modification to the database :
dotnet ef database update
But I then have the following error "FOREIGN KEY constraint failed" :
Here is the migration file generated :
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_DestinatairesPartageDocuments_Documents_DocumentId",
table: "DestinatairesPartageDocuments");
migrationBuilder.AddColumn<string>(
name: "StatutPartageExamen",
table: "Examens",
type: "TEXT",
nullable: true);
migrationBuilder.AlterColumn<int>(
name: "DocumentId",
table: "DestinatairesPartageDocuments",
type: "INTEGER",
nullable: true,
oldClrType: typeof(int),
oldType: "INTEGER");
migrationBuilder.AddColumn<int>(
name: "ExamenId",
table: "DestinatairesPartageDocuments",
type: "INTEGER",
nullable: true);
migrationBuilder.AddForeignKey(
name: "FK_DestinatairesPartageDocuments_Documents_DocumentId",
table: "DestinatairesPartageDocuments",
column: "DocumentId",
principalTable: "Documents",
principalColumn: "DocumentId",
onDelete: ReferentialAction.Restrict);
}
Below are the queries created from the migration :
My DbContext class :
public class ApplicationDbContext: IdentityDbContext<ApplicationUser>, IDataProtectionKeyContext
{
private readonly ILoggerFactory _loggerFactory;
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, ILoggerFactory loggerFactory) : base(options)
{
_loggerFactory = loggerFactory;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseLoggerFactory(_loggerFactory);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//modelBuilder.Entity<DestinatairePartageDocument>()
// .Property(dpd => dpd.DocumentId)
// .HasDefaultValueSql("NULL");
//modelBuilder.Entity<DestinatairePartageDocument>()
// .HasOne(dpd => dpd.Document)
// .WithMany()
// .OnDelete(DeleteBehavior.Cascade);
//modelBuilder.Entity<DestinatairePartageDocument>()
// .HasOne("PortailWorker.Models.Document", "Document")
// .WithMany()
// .HasForeignKey("DocumentId");
modelBuilder.Entity<DestinatairePartageDocument>()
.Property(ap => ap.DateCreation)
.HasDefaultValueSql("CURRENT_TIMESTAMP");
modelBuilder.Entity<DestinatairePartageDocument>()
.Property(ap => ap.DateDerniereModification)
.HasDefaultValueSql("CURRENT_TIMESTAMP");
modelBuilder.Entity<Revendeur>()
.HasMany(r => r.ListeClients)
.WithOne(c => c.Revendeur);
modelBuilder.Entity<ClientWPFFetcher>()
.HasKey(cwf => new { cwf.ClientId, cwf.WPFFetcherId });
modelBuilder.Entity<ClientWPFFetcher>()
.Property(cwf => cwf.RelationActivated)
.HasDefaultValue(true);
modelBuilder.Entity<ClientWPFFetcher>()
.HasOne(cwf => cwf.Client)
.WithMany(c => c.ClientWPFFetchers)
.HasForeignKey(cwl => cwl.ClientId);
modelBuilder.Entity<ClientWPFFetcher>()
.HasOne(cwf => cwf.WPFFetcher)
.WithMany(c => c.ClientWPFFetchers)
.HasForeignKey(cwl => cwl.WPFFetcherId);
modelBuilder.Entity<ClientWorkerLocal>()
.HasKey(cwl => new { cwl.ClientId, cwl.WorkerLocalId });
modelBuilder.Entity<ClientWorkerLocal>()
.Property(cwl => cwl.RelationActivated)
.HasDefaultValue(true);
modelBuilder.Entity<ClientWorkerLocal>()
.HasOne(cwl => cwl.Client)
.WithMany(c => c.ClientWorkersLocal)
.HasForeignKey(cwl => cwl.ClientId);
modelBuilder.Entity<ClientWorkerLocal>()
.HasOne(cwl => cwl.WorkerLocal)
.WithMany(c => c.ClientWorkersLocal)
.HasForeignKey(cwl => cwl.WorkerLocalId);
modelBuilder.Entity<Client>()
.Property(ap => ap.ActivationStatus)
.HasDefaultValue(1);
modelBuilder.Entity<Revendeur>()
.Property(ap => ap.ActivationStatus)
.HasDefaultValue(1);
modelBuilder.Entity<WorkerLocal>()
.Property(ap => ap.ActivationStatus)
.HasDefaultValue(1);
modelBuilder.Entity<ConfigurationWorker>()
.Property(cw => cw.Jpeg2000LossyRate)
.HasDefaultValue(40);
modelBuilder.Entity<ConfigurationWorker>()
.Property(cw => cw.ActiverBackgroundServiceWorker)
.HasDefaultValue(true);
modelBuilder.Entity<WorkerLocal>()
.Property(ap => ap.EnLigne)
.HasDefaultValue(false);
modelBuilder.Entity<WorkerLocal>()
.Property(ap => ap.UtilisationCPUPourcentage)
.HasDefaultValue(0.00);
modelBuilder.Entity<WorkerLocal>()
.Property(ap => ap.UtilisationRAMPourcentage)
.HasDefaultValue(0.00);
modelBuilder.Entity<WorkerLocal>()
.Property(ap => ap.UtilisationStockagePourcentage)
.HasDefaultValue(0.00);
modelBuilder.Entity<MappingHL7>()
.Property(m => m.SegmentId)
.HasDefaultValue(1);
modelBuilder.Entity<MappingHL7>()
.Property(m => m.ChampsHL7RepetitionId)
.HasDefaultValue(1);
modelBuilder.Entity<MappingHL7>()
.Property(m => m.SousComposantHL7)
.HasDefaultValue(1);
modelBuilder.Entity<MappingHL7>()
.Property(m => m.TypeMessage)
.HasDefaultValue("Tous");
}
public DbSet<RegleTraitementImage> ReglesTraitementImage { get; set; }
public DbSet<CritereSelectionRegle> CriteresSelectionRegle { get; set; }
public DbSet<AETDemandeur> AETDemandeurs { get; set; }
public DbSet<DestinatairePartageDocument> DestinatairesPartageDocuments { get; set; }
public DbSet<WPFFetcher> WPFFetchers { get; set; }
public DbSet<ClientWPFFetcher> ClientsWPFFetchers { get; set; }
public DbSet<ExamenAEnvoyer> ExamensAEnvoyer { get; set; }
public DbSet<ImageAEnvoyer> ImagesAEnvoyer { get; set; }
public DbSet<WorkerLocal> WorkersLocal { get; set; }
public DbSet<DestinationHL7> DestinationsHL7 { get; set; }
public DbSet<MessageHL7> MessagesHL7 { get; set; }
public DbSet<Patient> Patients { get; set; }
public DbSet<Examen> Examens { get; set; }
public DbSet<Medecin> Medecins { get; set; }
public DbSet<Correspondant> Correspondants { get; set; }
public DbSet<ExamensCorrespondants> ExamensCorrespondants { get; set; }
public DbSet<MappingHL7> MappingHL7 { get; set; }
public DbSet<ConfigurationWorker> ConfigurationWorker { get; set; }
public DbSet<DocumentStatus> DocumentStatus { get; set; }
public DbSet<Document> Documents { get; set; }
public DbSet<DocumentLogEvents> DocumentLogEvents { get; set; }
public DbSet<DestinatairePartage> DestinatairesPartage { get; set; }
public DbSet<Client> Clients { get; set; }
public DbSet<Revendeur> Revendeurs { get; set; }
public DbSet<ClientWorkerLocal> ClientWorkersLocal { get; set; }
public DbSet<DataProtectionKey> DataProtectionKeys { get; set; }
public DbSet<MappingExamenCompression> MappingExamenCompression { get; set; }
}
Has anyone any idea how to prevent this error from happening ?
I have tried changing the onDelete constraint but it didn't change anything.
Thanks for your help !
After clearing the table everything works fine.
I think I had foreign key id from my previous tests that didn't exist anymore in the original table.
Sorry to bother you !
I have a model
[AutoMap(typeof(WorkDTO), ReverseMap = true)]
public class WorkDTO
{
public Guid Id { get; set; }
public string UserId { get; set; }
public string Name { get; set; }
public string AvaUrl { get; set; }
public List<IFormFile> AvaWork { get; set; }
}
I have FluentValidator which is configured for this model.
public WorkDtoValidator()
{
RuleFor(p => p.Name)
.NotNull()
.NotEmpty()
.Length(2, 50)
.WithMessage("{PropertyName} should be not empty.");
RuleFor(p => p.Description)
.NotNull()
.NotEmpty()
.Length(50, 1000)
.WithMessage("{PropertyName} should be not empty.");
RuleFor(x => x.AvaWork).NotEmpty();
}
And configured it in StartUp
services.AddControllers()
.AddFluentValidation();
services.AddSingleton<IValidator<WorkDTO>, WorkDtoValidator>();
Validation work normal, but if I don`t send property AvaWork. If in model comes AvaWork than I get an exception
I tried without RuleFor(x => x.AvaWork).NotEmpty(); The same result. I Have a special validation class for validation AvaWork.
public class FileValidator : AbstractValidator<IFormFile>
{
public FileValidator()
{
RuleFor(x => x.Length).NotNull().LessThanOrEqualTo(100)
.WithMessage("File size is larger than allowed");
RuleFor(x => x.ContentType).NotNull().Must(x => x.Equals("image/jpeg") ||
x.Equals("image/jpg") || x.Equals("image/png"))
.WithMessage("File type is larger than allowed");
}
}
And added this line RuleForEach(x => x.AvaWork ).SetValidator(new FileValidator());
The same result.
If in controller will be only List<IFormFile> AvaWork (not model
public async Task<IActionResult> CreateWork(WorkDTO model)) It works good.
I don`t have any ideas.
The problem was in both sides. In front(Angular 11 - Typescript) I need add all properties to formData. By this way
const formData = new FormData();
formData.append('Name', this.createWorkForm.get('Name').value);
formData.append('Description', this.createWorkForm.get('description').value);
this.WorkMarkets.forEach(market => {
formData.append('Markets', market);
});
this.WorkingHours.forEach(session => {
formData.append('WorkingHours', session);
});
if (this.fileToUploadMain != null) {
formData.append('AvaWork', this.fileToUploadMain, this.fileToUploadMain.name);
}
this.apiWorkService.createWork(formData).subscribe(
suc => {
console.log(suc);
},
err => {
console.log(err);
});
And in back side add [FromForm] in Controller param
public async Task<IActionResult> CreateWork([FromForm]WorkDTO formWork)
Model of WorkDTO
public class WorkDTO
{
public Guid Id { get; set; }
public string UserId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public IEnumerable<string> WorkingHours { get; set; }
public IEnumerable<string> Markets { get; set; }
public string AvaUrl { get; set; }
public IFormFile AvaWork { get; set; }
}
I get this error:
Introducing FOREIGN KEY constraint may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
What is the problem in my code?
public class AppUserMap : IEntityTypeConfiguration<AppUser>
{
public void Configure(EntityTypeBuilder<AppUser> builder)
{
builder.Property(m => m.Name).HasMaxLength(50).IsRequired(true);
builder.HasMany(m => m.Essays).WithOne(m => m.AppUser).HasForeignKey(m => m.AppUserId);
}
}
public class AppRoleMap : IEntityTypeConfiguration<AppRole>
{
public void Configure(EntityTypeBuilder<AppRole> builder)
{
builder.HasKey(m => m.Id);
builder.HasMany(m => m.AppUsers).WithOne(m => m.AppRole).HasForeignKey(m => m.AppRoleId).OnDelete(DeleteBehavior.NoAction);
}
}
public class AppRole : IdentityRole<int>, ITable
{
public List<AppUser> AppUsers { get; set; }
}
public class AppUser : IdentityUser<int>, ITable
{
public string Name { get; set; }
public string Picture { get; set; } = "default.png";
#nullable enable
public string? AppUserRole { get; set; }
#nullable disable
public bool Ban { get; set; } = false;
public List<Essay> Essays { get; set; }
public AppRole AppRole { get; set; }
public int AppRoleId { get; set; }
}
Thank you for answering. I solved the issue by changing a couple of things in my code.
This is my solution code(you can see the changes):
public class AppUser : IdentityUser<int>, ITable
{
public string Name { get; set; }
public string Picture { get; set; } = "default.png";
public bool Ban { get; set; } = false;
public List<Essay> Essays { get; set; }
#nullable enable
public AppRole? AppRole { get; set; }
public int? AppRoleId { get; set; }
#nullable disable
}
public class AppRoleMap : IEntityTypeConfiguration<AppRole>
{
public void Configure(EntityTypeBuilder<AppRole> builder)
{
builder.HasKey(m => m.Id);
builder.HasMany(m => m.AppUsers).WithOne(m => m.AppRole).HasForeignKey(m => m.AppRoleId).OnDelete(DeleteBehavior.SetNull);
}
}
This question already has an answer here:
Many to many relationship mapping in EF Core
(1 answer)
Closed 3 years ago.
Dotnet Core 2.2, EntityFrameworkCore 2.2.3
In a Many-to-Many relation between the entities "Post" and "Category" the linked Entity "PostCategory" returns the "Post" object but for the "Category" object only the Id and not the object itself.
Migrations and database update works fine and all three tables are created.
For the relation itself I tried it with EF "auto magic" and explicit definition of the relation in OnModelCreating in the ApplicationDbContext.
Models
Post-Model
public class Post
{
public int Id { get; set; }
public string Slug { get; set; }
public string Title { get; set; }
public string Abstract { get; set; }
public string Content { get; set; }
public string Author { get; set; }
public DateTime Created { get; set; }
public ICollection<PostCategory> PostCategories { get; set; }
}
Category-Model
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public ICollection<PostCategory> PostCategories { get; set; }
}
PostCategory Model
public class PostCategory
{
public int PostId { get; set; }
public Post Post { get; set; }
public int CategoryId { get; set; }
public Category Category { get; set; }
}
DbSets in ApplicationDbContext
public DbSet<Post> BlogPosts { get; set; }
public DbSet<Category> BlogCategories { get; set; }
public DbSet<PostCategory> PostCategories { get; set; }
Get all Posts from Service
public IEnumerable<Post> GetAll()
{
var posts = _context.BlogPosts
.Include(x => x.PostCategories);
return posts;
}
Calling service from Controller
public IActionResult Index()
{
var blogPosts2 = _blogService.GetAll();
...
}
The result is seen in the screenshot.
In ApplicationDbContext I tried two versions:
Version 1:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<PostCategory>()
.HasKey(x => new { x.PostId, x.CategoryId });
}
public DbSet<Post> BlogPosts { get; set; }
public DbSet<Category> BlogCategories { get; set; }
public DbSet<PostCategory> PostCategories { get; set; }
Version 2:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<PostCategory>()
.HasKey(x => new { x.PostId, x.CategoryId });
builder.Entity<PostCategory>()
.HasOne(pt => pt.Post)
.WithMany(p => p.PostCategories)
.HasForeignKey(pt => pt.PostId);
builder.Entity<PostCategory>()
.HasOne(pt => pt.Category)
.WithMany(t => t.PostCategories)
.HasForeignKey(pt => pt.CategoryId); ;
}
public DbSet<Post> BlogPosts { get; set; }
public DbSet<Category> BlogCategories { get; set; }
public DbSet<PostCategory> PostCategories { get; set; }
Both version migrate and update with no errors and the same result.
I'm grateful for any help.
Best regards
Edit:
I tried the "ThenInclude" before but obviously my Visual Studio auto completion has a problem:
If I ignore the auto completion, then it works, thank you!
To eager load related data in multiple level, you have to use .ThenInclude as follows:
public IEnumerable<Post> GetAll()
{
var posts = _context.BlogPosts
.Include(x => x.PostCategories)
.ThenInclude(pc => pc.Category);
return posts;
}
Here is the more details: Loading Related Data: Including multiple levels