-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Option for migrations not to create foreign key constraints #21512
Comments
Duplicate of #18960 |
@John0King note that if you're using
Can you provide more detail on this, i.e. why someone would avoid defining a foreign key but still define an index? In any case, EF Core certainly needs to have a relationship defined between tables in order to do any cascading deletes, and that indeed requires a foreign key. |
that's not true, the database automatically delete is did by that you add
stackoverflow https://stackoverflow.com/questions/599159/should-i-use-foreign-keys is the discussion and this is the https://developer.aliyun.com/article/709387
translate :
EF is a business layer technology , it is an ORM, it should manage all the relationship between our mapped Object , but it current is a database design tool , it create the relation that make the database to managed it , EF should force on manage relation/ handle relation and translate sql more flexible, for example look at the community is doing
Task UpdateAsync<TEntity>(IQuerable<TEntity> condition, Expression<Func<TEntity,object>> updateExpression)
Task UpdateAsync<TEntity>(IQuerable<TEntity> condition, object updateConstantObject)
Task RemoveAsync<TEntity>(IQuerable<TEntity> condition);
Task RemoveAsync<TEntity>(Expression<Func<TEntity,bool>> condition);
// for changed entity we may add a new parameter "bool updateTrackedEntity = false"
// and translate the updateExpression and delete expression again for `db.ChangeTracker.Entries<TEntity>()`
``` |
@John0King I wasn't trying to say you're wrong in any way. For users which are OK with the database implementing the cascade delete (via foreign keys), the DeleteBehavior.Cascade does that - this seems to be the majority case, except for some limitations in SQL Server related to circularity. For users who don't want to use DeleteBehavior.Cascade - either because of the SQL Server limitation, or because their database policy precludes foreign keys or database-side cascade - the DeleteBehavior.ClientCascade exists precisely to perform the cascade on the client, which is what you are asking for. However, at this point ClientCascade only deletes tracked entities, and #18960 tracks doing a bulk delete in order to cascade. Therefore this issue seems to be a duplicate of #18960, or have I misunderstood your request? |
@roji yes the main issue maybe a duplicate ,
|
@John0King if I'm understanding you correctly, you want to use EF Core migrations, but don't want EF Core to create foreign constraints. If so, this isn't really related to to cascading - it's how EF Core generates migrations for relationships. Can you please confirm this is what you're looking for?
Can you please provide more detail on what this means, including a code sample?
Already tracked by #18960 as discussed above. |
|
I'm confused... What is it exactly that you'd like migrations to do for you? Above you mentioned you don't want foreign key constraints, which is what migrations introduce for relationships. Any sort of cascade solution based on bulk delete would be purely client-side, as EF would automatically send DELETE statements to cascade - no need for any migrations... Can you please explain what it is you're looking for?
I think @smitpatel addressed everything in that issue.
General support for bulk delete/update is tracked by #795 - this would include a public, user-facing API for doing arbitrary bulk operations. The implicit use of bulk delete/update to implement client-managed cascading deletes is tracked by #18960. Is there anything not already tracked by other issues that requires keeping this open? |
@roji entity: public class Blog
{
public int Id{get;set;}
public List<Post> Posts {get;set;}
}
public class Post
{
public int Id{get;set;}
public int BlogId {get;set;}
public Blog Blog{get;set;}
} we do not want Post to have a FOREIGN KEY in Database, but without a new fulent API like if this fluent-API is been noticed , then this issue can be close now |
To be clear, what you want is for migrations to not create the constraint in the database, right (the foreign key column must still be created, otherwise there is no way to represent that the entities are related)? If this is what you're looking for, then as a workaround you can edit your migrations after adding them and manually remove the foreign key constraints. I must say I have serious doubts about the advice to not use foreign key constraints for the general case. Sure, there may be some extreme edge cases where foreign keys may cause performance issues, and you may pay a very small price at insertion time for the checks, but that's likely to be negligible for all but very specific/high-perf applications. I would highly recommend using foreign key constraints unless careful benchmarking empirically shows them to be problematic in your specific case. |
Related: #13146 |
For the query part of the issue,
|
@smitpatel and join optimizations without database constraint will never be correct, if there no include,there will no john , perform a join optimizations will not be need, so remove the join optimizations seems a right direction |
@John0King - Your statements seem to be contradicting.
If your ask is that user will define FK in EF Core model but it does not exist in database then there is no query issue as above will continue to happen since model contains the FK. Regardless of constraint not defined in database, if EF Core has it then your data need to be consistent graph. There is just no enforcement of it. But it does not allow you to have a dependent without a parent. If you have issue with join then make sure your FK definition in EF Core model is correct and consistent with data. If you don't want to have FK in your EF Core model then you can have data in database whichever way you want but you cannot use navigations in the queries. You must use join operator yourself to join tables. |
We discussed this again and concluded that we don't want to allow normal (i.e. not the kind of constraint described in #13146) FK constraints to be excluded from migrations as a first-class option. Instead, the constraint can be removed from the migration code generated so that it is not created in the database. This will not change EF behavior with regard to the FK. |
So sharding a table isn't a use case? Can't believe noone has mentioned this. While in code, it makes sense to see the database as if there is a foreign key. But from a database level having a foreign key can create as many problems as it solves when scaling a database (sharding). I personally believe that it is much better to handle deletes in code rather than leaving it to the database. It forces the developer to really think how to handle deletion in all cases. Saying this shouldn't be a first class option just blows my mind. |
Another use case is using partitioned tables like the one that TimescaleDB provide. Where their "hypertables" are tables that partition on the timestamp. These hypertables do not support foreign key constraints but work just fine using joins. |
from https://docs.microsoft.com/en-us/ef/core/saving/cascade-delete#cascading-to-untracked-entities
as an Object Relational Mapping Framework, and we spend much time to create the model, I think EF should
care about the relation in Model instead of use something-else ( today use database's ability) to perform
CascadeDelete
if parent entity is delete, then it's children should be delete to when configure to
DeleteBehavior.Cascade
, and this can be done by a simpleDELETE FROM <Table> WHERE <ForeignKey> = @ParentPrimaryKey
, and EF should scan the model to perform multiple level of CascadeDelete in correct order. and forDeleteBehavior.SetNull
is the sameand in many big table (millions of data) , people often not use
ForeignKey
, instead they only use index, EF Core do not support this neither. (skip foreight key) and in this case , the pagination query is also has a problem when you useNone-Nullable Type
as Foreign Key ,(caused by skip theJOIN
) , For example:because without the
inner join
thetotal
can be bigger than it shouldThe text was updated successfully, but these errors were encountered: