I try to set a unique constraint on multiple columns of which one also is a foreign key. I have tried a few things and are out of ideas by now.
To get a better understanding of what the context is and what I am trying to do, please consider the follwing example:
Let's say we have two classes:
[Table(nameof(DeviceModel), Schema="DevModel")]
public class DeviceModel
{
[Key]
public int Id {get;set;}
[Required]
public string Name {get; set;}
[Required]
public string Vendor { get; set; }
public string Description {get; set;}
}
[Table(nameof(Device), Schema="DevModel")]
public class Device
{
[Key]
public int Id {get; set;}
[Required]
public DeviceModel Model {get;set;}
[Required]
public int SerialNumber {get;set;}
[Required]
public int InventoryNumber {get;set;}
}
These two classes are mapped to a table Device
and a table DeviceModel
.
Each of the tables has a primary key Id
.
Device
references DeviceModel
via a foreign key column ModelId
.
As each device of a certain type should obtain a unique inventory number as well as has to have a unique serial number per DeviceModel
I would like to define a uniqueness constraint on Device.InventoryNumber
as well as on Device.{Model, SerialNumber}
(pseudo syntax).
For achieving this in the corresponding DbContext instance I override the OnModelCreating
method as shown below:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Device>()
.HasIndex(i => new { i.Model, i.SerialNumber }).IsUnique();
modelBuilder.Entity<Device>()
.HasIndex(i => i.InventoryNumber).IsUnique();
}
While setting up the unique constraint for InventoryNumber
works just fine, setting up the unique constraint for the column pair {Model, Serialnumber}
fails.
The corresponding exception text is:
The property 'Device.Model' is of type 'DeviceModel' which is not supported by the current database provider. Either change the property CLR type, or ignore the property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
As the constraint actually should apply to the {ModelId, SerialNumber}
columns, I also tried to set up the unique constraint like this:
modelBuilder.Entity<Device>().HasIndex(i => new { i.Model.Id, i.SerialNumber }).IsUnique();
This results in error message:
The expression 'i => new <>f__AnonymousType0`2(Id = i.Model.Id, SerialNumber = i.SerialNumber)' is not a valid member access expression. The expression should represent a simple property or field access: 't => t.MyProperty'. When specifying multiple properties or fields, use an anonymous type: 't => new { t.MyProperty, t.MyField }'. (Parameter 'memberAccessExpression')
Also I thought about defining a custom conversion from Model
to int
but this will most likely result in figuring out, how to convert a primary key to an DeviceModel
instance which is kind of reimplementing what entity framework should do for me.
So far I am out of ideas how to accomplish a unique constraint on multiple columns that contain at least one foreign key column.
Any ideas on how I could get this accomplished?