Finbuckle / Finbuckle.MultiTenant

Finbuckle.MultiTenant is an open-source multitenancy middleware library for .NET. It enables tenant resolution, per-tenant app behavior, and per-tenant data isolation.
https://www.finbuckle.com/multitenant
Apache License 2.0
1.26k stars 258 forks source link

Add TenantNotSetMode.OverwriteIfNullOrEmpty #782

Open fretje opened 5 months ago

fretje commented 5 months ago

See our conversation: https://github.com/Finbuckle/Finbuckle.MultiTenant/discussions/612#discussioncomment-8153634:

Hi @AndrewTriesToCode. Maybe I wasn't making myself clear... I don't want a record with a null (or empty) tenantId value... I want Finbuckle to take care of (i.e. set) the tenantId, just like it does with all the other tenantId's in the database... It's just that in this case, the tenantId is part of the primary key, which means I can't use DbContext.Set<T>.Add(entity) with an entity that has that tenantId set to null. You get an EF Core exception when you try to do that. I can add it when the tenantId is emtpy though... but then it doesn't get picked up by Finbuckle when I use TenantNotSetMode, only with TenantMismatchMode...

I guess my question is: could the test you do with TenantNotSetMode use string.IsNullOrEmpty(tenantId) in stead of tenantId is null? ;-)

Originally posted by @fretje in https://github.com/Finbuckle/Finbuckle.MultiTenant/discussions/612#discussioncomment-8153634

hi @fretje

That would be a breaking change, maybe another value for that like TenantNotSetMode.OverwriteIfNullOrEmpty? Would you mind creating a new issue for this?

Originally posted by @AndrewTriesToCode in https://github.com/Finbuckle/Finbuckle.MultiTenant/discussions/612#discussioncomment-8227865

AndrewTriesToCode commented 4 months ago

I'm going to look further into this. I'm rethinking some of the EF Core stuff overall so I appreciate your ideas. Have you looked at using generators or similar EFCore capability to set the tenant when using Add?

fretje commented 4 months ago

Not sure what you mean with "generators"...

I'm using "TenantMismatchMode.Overwrite" for now...

If I don't do that, I have to set the "TenantId" property manually (take it from ITenantInfo) before adding the entity to the dbcontext.

Note that this is only the case for entities where the TenantId is part of the primary key. For other (multitenant) entities (that don't have the TenantId as part of their primary key) I don't even have a "TenantId" property on the entity. There then Finbuckle is taking care of everyting "behind the scenes"... It would be nice if that would also be possible for entities where the TenantId is part of the primary key... But I'm not sure that's even possible with EF Core (i.e. to have an entity where part of its primary key is a shadow property).

AndrewTriesToCode commented 4 months ago

This is what I was referring to: https://learn.microsoft.com/en-us/ef/core/modeling/generated-properties?tabs=data-annotations#primary-keys

Do you think that would help in your use case?

fretje commented 4 months ago

Oh, you mean database generated id's... well, I can't use those in this case, as here, the "primary key" of the entity (from the tenants perspective) is a user-supplied string, so it needs to be unique, but only per tenant (i.e. 2 separate tenants could use the same primary key here, hence why tenantId needs to be part of the primary key...)

In other cases, I'm indeed using a db generated (identity) id, but in this case that's not possible.