C
C#7mo ago
Lounder

✅ EF Core navigational properties

This works fine (no navigational property to Business):
class Business
- ...
- Address Address { get; set; }

class Address
- ...
class Business
- ...
- Address Address { get; set; }

class Address
- ...
This causes an error:
class Business
- ...
- Address Address { get; set; }

class Address
- ...
- Business { get; set; }
class Business
- ...
- Address Address { get; set; }

class Address
- ...
- Business { get; set; }
InvalidOperationException: The value of 'Address.Id' is unknown when attempting to save changes. This is because the property is also part of a foreign key for which the principal entity in the relationship is not known
InvalidOperationException: The value of 'Address.Id' is unknown when attempting to save changes. This is because the property is also part of a foreign key for which the principal entity in the relationship is not known
Initialization code:
var address = new Address
{
Street = "SName",
City = "CName",
};

await dbContext.Addresses.AddAsync(address);
var address = new Address
{
Street = "SName",
City = "CName",
};

await dbContext.Addresses.AddAsync(address);
How can I make this work while also keeping Address' nav property to Business? Please @ me so I respond immediately
27 Replies
Angius
Angius7mo ago
I assume
- Business { get; set; }
- Business { get; set; }
is supposed to be
- Business Business { get; set; }
- Business Business { get; set; }
? Also, don't use .AddAsync(), it's not an inherently asynchronous operation.
Lounder
Lounder7mo ago
I just solved the problem Old code:
builder.Entity<Business>()
.HasOne(b => b.Address)
.WithOne(a => a.Business)
.HasForeignKey<Address>(a => a.Id);
builder.Entity<Business>()
.HasOne(b => b.Address)
.WithOne(a => a.Business)
.HasForeignKey<Address>(a => a.Id);
New code:
builder.Entity<Address>()
.HasOne(b => b.Business)
.WithOne(a => a.Address)
.HasForeignKey<Business>(a => a.Id);
builder.Entity<Address>()
.HasOne(b => b.Business)
.WithOne(a => a.Address)
.HasForeignKey<Business>(a => a.Id);
I initialize Address first so I suppose it must be the "primary" entity or however it is called.
Jimmacle
Jimmacle7mo ago
you shouldn't have to do either of those, that relationship should be discovered by convention
Lounder
Lounder7mo ago
I do this so I could get the business entity from the address entity: Address.Business.Id for example
Jimmacle
Jimmacle7mo ago
that's fine, i'm staying this is a basic relationship that you do not need to configure yourself
Lounder
Lounder7mo ago
In this case it isn't very useful but I imagine that in the other entities I will need this and I guess it's better to have it the same everywhere
Jimmacle
Jimmacle7mo ago
EF should automatically set it up
Lounder
Lounder7mo ago
Are you talking about fluent api
Jimmacle
Jimmacle7mo ago
yes
Lounder
Lounder7mo ago
I get an error without it Something along the lines of "can't determine parent" Aka what points to what
Jimmacle
Jimmacle7mo ago
weird i'd personally make the address an owned entity
Lounder
Lounder7mo ago
Maybe I'm just doing something wrong Can you define owned entity First time hearing it
Jimmacle
Jimmacle7mo ago
it will be stored in-line in the business table
Lounder
Lounder7mo ago
Oh so no mention in dbcontect as dbset?
Jimmacle
Jimmacle7mo ago
so your business table gets columns like Address_Street, Address_City, etc right to me an address isn't an entity, it's just a value so it doesn't make sense to treat it like an independent thing
Lounder
Lounder7mo ago
Isn't this applicable to every one to one relationship
Jimmacle
Jimmacle7mo ago
theoretically but think of it this way a business has an address, but does it necessarily make sense for an address to have a business or no business at all? (it might, depends on your requirements)
Lounder
Lounder7mo ago
I think an address should have a business because you could search up the street name or the city And the business/es would pop up as results
Jimmacle
Jimmacle7mo ago
you can do that whether it's owned or not, it just changes the table the data lives in
Lounder
Lounder7mo ago
Oh or maybe you mean that We never get the address as a separate entity, it is always interlocked with business So it makes it useless to be seperate when you always call the business entity
Jimmacle
Jimmacle7mo ago
right
Lounder
Lounder7mo ago
Gotcha I agree
Jimmacle
Jimmacle7mo ago
so it sounds like there's no reason for an address to be able to exist in the database all by itself
Lounder
Lounder7mo ago
Right Okay I will work on that, thank you I will close this thread now, good night 👋
Jimmacle
Jimmacle7mo ago
iirc EFC 8 has better support for complex types without making them owned, could look into that too
Lounder
Lounder7mo ago
I'm limited to net 6
Jimmacle
Jimmacle7mo ago
ah, owned it is then