When I insert a new MaskField
model into my database using Entity Framework Core it also inserts a Restriction
model which is referenced inside the MaskField
model. I am trying to get it to only reference a Restriction
object as I already know the object exists when trying to reference it inside MaskField
.
I have a MaskField
model defined:
[Table("MaskField", Schema = "dbo")]
public class MaskField
{
[Key]
public int maskId { get; set; }
public Restriction? restriction { get; set; }
}
That MaskField
model references a single Restriction
model inside it. This is the Restriction
model:
[Table("Restriction", Schema = "dbo")]
public class Restriction
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int restrictionId { get; set; }
[Required]
public string? restrictionName { get; set; }
[Required]
public string? regex { get; set; }
}
My DbContext
:
public class MaskContext : DbContext
{
public MaskContext(DbContextOptions options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MaskField>((mf) =>
{
mf.HasKey(e => new { e.maskId });
mf.HasOne(e => e.restriction).WithMany();
});
}
public DbSet<MaskField> MaskFields { get; set; }
public DbSet<Restriction> Restrictions { get; set; }
}
Trying to insert a MaskField
that contains a restriction ends up executing:
INSERT INTO [dbo].[Restriction] ([restrictionId], [regex], [restrictionName])
VALUES (@p0, @p1, @p2);
Which ends up erroring because IDENTITY_INSERT
is disabled. Any ideas on how to just reference it instead of it trying to insert a new Restriction
model?
EDIT: This is the code for inserting a MaskField
public class MaskRepository : IMaskRepository
{
MaskContext dbContext;
public MaskRepository(MaskContext dbContext)
{
this.dbContext = dbContext;
}
public async Task<MaskField> CreateAsync(Mask _object)
{
var obj = await dbContext.MaskFields.AddAsync(_object);
dbContext.SaveChanges();
return obj.Entity;
}
}
CodePudding user response:
I have found a not so nice workaround for this.
So to just reference the Restriction
is fairly simple just change the line
public Restriction? restriction {get;set;}
to reference the key for Restriction
like: public int? restrictionId {get;set;}
However since I wanted to extract the whole Restriction
object in the one query I was forced to have both fields like this:
[Table("MaskField", Schema = "dbo")]
public class MaskField
{
[Key]
public int maskId { get; set; }
public int? restrictionId { get; set; }
public Restriction? restrictionId { get; set; }
}
This seems like a good solution until I realised that when saving/ updating that object to the database it causes the same original problem.
To work around this I have added logic in the saving and updating functions to set those fields to null before saving:
public class MaskRepository : IMaskRepository
{
MaskContext dbContext;
public MaskRepository(MaskContext dbContext)
{
this.dbContext = dbContext;
}
public async Task<MaskField> CreateAsync(MaskField _object)
{
_object.restriction = null;
var obj = await dbContext.MaskFields.AddAsync(_object);
dbContext.SaveChanges();
return obj.Entity;
}
}
CodePudding user response:
Finally found a proper resolution to this problem.
You can add the [JsonIgnore]
field to model classes to stop models from even being submitted to ef core in the first place.
In this case it will be:
[Table("MaskField", Schema = "dbo")]
public class MaskField
{
[Key]
public int maskId { get; set; }
public int? restrictionId { get; set; }
[JsonIgnore]
public Restriction? restriction { get; set; }
}