-
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
Basic support for creating entities on partitioned tables in SQL Server (Code-First) #33505
Comments
Describe the solution you'd like (cont'd)I don't know exactly which part of the system should pick up the I'm going to be less precise when talking about how the
Taking a look at that, I think I would be almost as happy if only partitioned indexes are supported with this. I'd have to make sure to hit all indexes, including the ones created by Nice-to-have future workEven once the tables are created, for these specific entities, EF Core basically will only help us with queries. All the manipulation of these data sets is going to have to go through hand-rolled SQL and To insert a new self-contained bundle of rowsPrerequisites:
Assumptions:
Steps:
To delete a self-contained bundle of rowsPrerequisite and assumptions are the same as inserting the new bundle. Steps (before SQL Server 2016):
Steps (SQL Server 2016+) (I have not tested this variant):
|
Thanks @airbreather. Without diving too deep, this is probably one of those DDL features where there would be relatively less value in 1st-class EF support (and where that support would be a lot of work); there are a lot of various table configuration features across databases, where users can simply use custom SQL directly in their migrations to achieve what they want. For example, specifically on this: modelBuilder
.HasPartitionFunction(createSql: "CREATE PARTITION FUNCTION PF_Blog /* ... */")
.HasPartitionScheme(createSql: "CREATE PARTITION SCHEME PS_Blog /* ... */"); Since the function and scheme are defined as SQL in any case, HasPartitionFunction/Scheme really provide little advantage over simply introducing the appropriate CREATE PARTITION directly into a migration. Modeling features in EF can sometimes be useful where users can change some aspect of the object, and EF knows how to alter that aspect in the database, but here we're really dealing with a function/scheme definition which is just a SQL. So the value here seems very limited. Allowing specifying partitioning on CREATE TABLE has a bit more value, since it allows users to continue using regular EF modeling for table creation, rather than the alternative of replacing EF's CreateTable() in migrations with SQL that includes the partition (though that's not a terrible workaround either for those tables which are partitioned). I'll also just note that this is the first time IIRC that we've received a request to support partitioning on SQL Server (note similar request for table partitioning on the PostgreSQL side which has received lots of votes and interest over the years: npgsql/efcore.pg#1035). |
If not for the wrinkle about As it stands, from my perspective (I've got to run right now, so I can't elaborate), if the "regular EF modeling for table creation" part were implemented without this, then it looks like there's no way to use |
Yeah, EnsureCreatedAsync is indeed incompatible with custom SQL, and that's (only) one reason why it's generally unsuitable for real applications. It really is a feature for test code and demos, nothing more - so yeah, I don't think there's a way to use EnsureCreatedAsync and have partitioned tables (or any other DDL/migration feature that EF doesn't handle). |
That makes sense. For context, we use it to initially create a LocalDB database for automated tests that we immediately wipe out with a I can just switch that |
Yep, test database management is indeed a whole domain that can be pretty complex :) So yeah, I'd definitely recommend switching to MigrateAsync for your test database creation; assuming you do use migrations for your production app, this also guarantees that your tests run on the same database schema that your actual app does (notably around questions of custom SQL). The main possible disadvantage of that is that if you start to have a big migration history, that history gets replayed when creating the test database; a possible mitigation is to squash your migration history every now and then and start over. Though if you're creating your database only once when starting a CI run (which is generally good), that hopefully isn't a big deal. Data seeding specifically is something that should generally be handled separately (especially if lots of data is involved), and so should be orthogonal to how you create your database or schema (i.e. EnsureCreated or Migrate). |
When I wanted to use efcore and pgsql to implement a partition table, I read a lot of information and finally found that there was no support (npgsql/efcore.pg#1035). I am a little overwhelmed now. I hope efcore can support it. |
Background
SQL Server supports something called partitioned tables. In one of our ORM-free legacy applications, we've used this functionality to great effect to accelerate managing large data sets with minimal logging, after our first attempt at these kinds of tools backfired when the transaction log file tried to outgrow the disk it was on.
What problem are you trying to solve?
Trying to replicate our solution in another application, which uses EF Core (Code-First style), has been a challenge. With many other SQL Server features, even if EF Core doesn't support them directly,
migrationBuilder.Sql("...");
is good enough......but not for partitioned tables. I can't just create a table (or index) as normal and then issue a command that says "take this existing table (or index) and put it onto that partition scheme". The table (or index) needs to be created on that partition scheme, so the entire
CREATE TABLE
or (CREATE INDEX
) would need to go intomigrationBuilder.Sql("...");
.My first thought was to do
CREATE PARTITION FUNCTION
/CREATE PARTITION SCHEME
inmigrationBuilder.Sql("...");
as normal, and then inherit fromSqlServerMigrationsSqlGenerator
and overrideGenerate(CreateTableOperation, ...)
to tweak theCREATE TABLE
statement to addON ThePartitionScheme(ThePartitioningColumn)
to the right spot (given the right custom annotations).This was incomplete:
RelationalDatabaseCreator.EnsureCreatedAsync
tries to run those very migration operations* when the database is created, and so I also needed myGenerate(CreateTableOperation, ...)
override to be able to start by creating the partition function and scheme if those do not exist.DatabaseFacade.EnsureCreatedAsync
emphatically claiming that it doesn't use migrationsUltimately, I have something that I think is going to be functional for a while, but I'm worried how much custom code I had to write in order to do this, including a suppression or two for
EF1001
.Describe the solution you'd like
I don't think my use case needs particularly rich support in order to see a huge improvement. I think that I would be happy if I could write something like this in my
DbContext
:I'm going to keep this initial post short and add more context, thoughts, and details into a comment.
The text was updated successfully, but these errors were encountered: