My scenario is for investment in properties (buildings). An investor makes an investment in a property group, and that group can contain several individual properties. As investors can invest in multiple groups, and any group can have multiple investors, the investment itself is a many-to-many relationship between the investors and property groups.
Ignoring the simple properties for clarity, the models look like this...
public class Investor {
public int ID { get; set; }
public ObservableCollection<Investment> Investments { get; set; }
}
public class Investment {
public int ID { get; set; }
public int InvestorID { get; set; }
public virtual Investor Investor { get; set; }
public int PropertyGroupID { get; set; }
public virtual PropertyGroup PropertyGroup { get; set; }
}
public class PropertyGroup {
public int ID { get; set; }
public ObservableCollection<Property> Properties { get; set; }
public ObservableCollection<Investment> Investments { get; set; }
}
public class Property {
public int ID { get; set; }
public int PropertyGroupID { get; set; }
public virtual PropertyGroup PropertyGroup { get; set; }
}
This all works fine.
I now have the requirement to generate and store documents. These will always be associated with a specific investor, but may also be associated with a property or a group.
I added the following class...
public class Document {
public int ID { get; set; }
// Other simple properties omitted for clarity
public int InvestorId { get; set; }
public Investor Investor { get; set; } = null!;
public int? PropertyGroupId { get; set; }
public PropertyGroup? PropertyGroup { get; set; }
public int? PropertyId { get; set; }
public Property? Property { get; set; }
}
In order to provide the navigation links into the documents, I added the following line into the Investor
, PropertyGroup
and Property
models...
public ObservableCollection<Investment> Documents { get; set; }
When I try to add a migration, I get an error "Unable to determine the relationship represented by navigation 'Investment.Investor' of type 'Investor'."
Reading the output from the migration, I see a message "No relationship from 'Investment' to 'Investor' has been configured by convention because there are multiple properties on one entity type - {'Investor'} that could be matched with the properties on the other entity type - {'Documents', 'Investments'}."
I don't understand either message, as I do have an explicit relationship defined from Investment
to Investor
as you can see above. I have an int
property called InvestorId
and a navigation property of type (and name) Investor
. I'm not sure what the last bit of the second message means.
However, I added the following to OnModelCreating
...
builder.Entity<Investment>()
.HasOne<Investor>()
.WithMany(i => i.Investments)
.HasForeignKey(i => i.InvestorID)
.OnDelete(DeleteBehavior.Restrict);
This got rid of that error, but gave a similar one, "Unable to determine the relationship represented by navigation 'Investment.PropertyGroup' of type 'PropertyGroup'." I added the following...
builder.Entity<Investment>()
.HasOne<PropertyGroup>()
.WithMany(i => i.Investments)
.HasForeignKey(i => i.PropertyGroupID)
.OnDelete(DeleteBehavior.Restrict);
This allowed the migration to be added, but it included the following in the Up
method...
migrationBuilder.AddColumn<int>(
name: "InvestorID1",
table: "Investments",
type: "int",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "PropertyGroupID1",
table: "Investments",
type: "int",
nullable: false,
defaultValue: 0);
I can see the migration output contains a warning "The foreign key property 'Investment.InvestorID1' was created in shadow state because a conflicting property with the simple name 'InvestorID' 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." but I don't understand what it means.
Anyone able to explain what I'm doing wrong? Thanks
CodePudding user response:
There is something missed(typo), to make relation with Document
you have to define collection props
of Document
not Investments
so change
public ObservableCollection<Investment> Documents { get; set; }
to
public ObservableCollection<Document> Documents { get; set; }