I am trying to use EF Core with MongoDB, I’ve grouped additional info to separate classes MyInfo
and ThirdpartyInfo
.
internal class MyObject
{
[BsonId]
public ObjectId Id { get; set; }
public string Name { get; set; }
public MyInfo? Info { get; set; }
public ThirdpartyInfo? Thirdparty { get; set; }
}
internal class ThirdpartyInfo
{
public int UserId { get; set; }
public int MyObjectId { get; set; }
}
internal class MyInfo
{
public string Property1 { get; set; }
public string Property2 { get; set; }
}
class MyDbContext : DbContext
{
public DbSet<MyObject> Test { get; init; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<MyObject>().ToCollection("tests");
}
}
With MyInfo
I have no problem, it saves perfectly and generates no warnings. ThridpartyInfo.MyObjectId
property seems to conflict with EF Core conventions, and generates following warning below, but I could not rename it.
warn: Microsoft.EntityFrameworkCore.Model.Validation[10625] The
foreign key property ‘ThirdpartyInfo.MyObjectId1’ was created in
shadow state because a conflicting property with the simple name
‘MyObjectId’ exists in the entity type, but is either not mapped, is
already used for another relationship, or is incompatible with the
associated primary key type. See https://aka.ms/efcore-relationships
for information on mapping relationships in EF Core.
Is there any way to ignore any conventions for ThirdpartyInfo
class? I’ve tried
modelBuilder.Ignore<ThirdpartyInfo>();
and there is no warning after that, but property itself won’t be written back to datastore at all. There is no problem with warning except it looks unprofessional and I really wouldn’t like to see it in production.
2
Answers
Well, I've solved my problem by renaming property and setting datastore column name to old name to assure existing data still be valid:
Then EF Core throws no warnings while running.
With one-to-one relationships, EF will default to attempt to join the entities by their respective PKs. For instance:
The type of each PK needs to match. Now if the MyObjectId is not the PK for the ThirdPartyInfo then you need to explicitly configure the relationship to tell EF which property, and on which side of the relationship the FK or Principal key resides.
However note that in this case the FK type still needs to match. If MyObject PK is this ObjectId type, then the FK in ThirdPartyInfo needs to match. This is what EF is doing with a shadow property to resolve the issue, it created the MyObjectId1 with a suitable Type since MyObjectId was not up to the task. (wrong type)
If you need to use an Int for the FK then you would need a suitable PricipalKey on the MyObject side: