I looked through many similar questions, but I find no applicable solution.
I get the following error message during tests:
System.InvalidOperationException : The relationship from 'Product.FeatureType' to 'FeatureType.Product' with foreign key properties {'Type' : string} cannot target the primary key {'Id' : Guid} because it is not compatible. Configure a principal key or a set of compatible foreign key properties for this relationship.
The foreign key should be FeatureType's Type field.
This only happens, when I set the type of Product.Type as a string and as not as a Guid. But it should be a string, rather than a Guid. I do not understand at all what is the problem here. I do the project in a DB-first approach and the database can be created without a problem with SQL using this logic. I appreciate every help.
I have the following models:
public class Product : IDBModel
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public DateTime SysStartTime { get; set; }
public DateTime SysEndTime { get; set; }
public FeatureType FeatureType { get; }
}
public class FeatureType : IDBModel
{
public Guid Id { get; set; }
public string Type { get; set; }
public Guid? Description { get; set; }
public DateTime SysStartTime { get; set; }
public DateTime SysEndTime { get; set; }
public TxtID TxtIDDescription { get; set; }
public ICollection<Feature> Feature { get; }
public ICollection<Product> Product { get; }
}
And the following related context configuration:
public virtual DbSet<Product> Product { get; set; }
public virtual DbSet<FeatureType> FeatureType { get; set; }
...
modelBuilder.Entity<Product>(entity =>
{
entity.ToTable("Product", CoreSchema)
.HasKey(k => new { k.Id })
.HasName("PK_Product");
entity.Property(a => a.Id).HasColumnName("id");
entity.Property(a => a.Name).HasColumnName("name").IsRequired();
entity.Property(a => a.Type).HasColumnName("type").HasMaxLength(50).IsRequired().IsUnicode(false);
entity.Property(e => e.SysStartTime).HasColumnName("SysStartTime").ValueGeneratedOnAddOrUpdate();
entity.Property(e => e.SysEndTime).HasColumnName("SysEndTime").ValueGeneratedOnAddOrUpdate();
entity.HasOne(p => p.FeatureType)
.WithMany(d => d.Product)
.HasForeignKey(p => p.Type)
.OnDelete(DeleteBehavior.Restrict);
});
modelBuilder.Entity<FeatureAttributeSet>(entity =>
{
entity.ToTable("FeatureAttributeSet", "Core")
.HasKey(e => new { e.Id })
.HasName("PK_FeatureAttributeSet");
entity.Property(e => e.Id).HasColumnName("id").IsRequired();
entity.Property(e => e.AttributeSetId).HasColumnName("as_id").IsRequired();
entity.Property(e => e.FeatureId).HasColumnName("feature_id").IsRequired();
entity.Property(e => e.SysStartTime).ValueGeneratedOnAddOrUpdate();
entity.Property(e => e.SysEndTime).ValueGeneratedOnAddOrUpdate();
entity.HasOne(d => d.AttributeSet)
.WithMany(p => p.FeatureAttributeSet)
.HasForeignKey(d => d.AttributeSetId)
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("FK_FeatureAttributeSet_AttributeSet");
entity.HasOne(d => d.Feature)
.WithMany(p => p.FeatureAttributeSet)
.HasForeignKey(d => d.FeatureId)
.OnDelete(DeleteBehavior.Restrict)
.HasConstraintName("FK_FeatureAttributeSet_Feature");
});
CodePudding user response:
The solution is to configure the PrincipalKey. The PrincipalKey will allow us to define the reference key with a unique restriction which will be the destination of the relationship. So you can use like this
modelBuilder.Entity<Product>(entity =>
{
entity.ToTable("Product", CoreSchema)
.HasKey(k => new { k.Id })
.HasName("PK_Product");
entity.Property(a => a.Id).HasColumnName("id");
entity.Property(a => a.Name).HasColumnName("name").IsRequired();
entity.Property(a => a.Type).HasColumnName("type").HasMaxLength(50).IsRequired().IsUnicode(false);
entity.Property(e => e.SysStartTime).HasColumnName("SysStartTime").ValueGeneratedOnAddOrUpdate();
entity.Property(e => e.SysEndTime).HasColumnName("SysEndTime").ValueGeneratedOnAddOrUpdate();
entity.HasOne(p => p.FeatureType)
.WithMany(d => d.Product)
.HasPrincipalKey(p => p.Type)
.HasForeignKey(p => p.Type)
.OnDelete(DeleteBehavior.Restrict);
});
CodePudding user response:
The foreign key that you specify in your model builder statement for the FeatureType of Product in .HasForeignKey(p => p.Type) must be the same type as the primary key of FeatureType. Because the Id property of FeatureType is a Guid, Type on Product must also be of type Guid to be used as the foreign key for the relationship with FeatureType.
Is there a reason that you can't change the type of the Type property to Guid?
