dotnet / EntityFramework.Docs

Documentation for Entity Framework Core and Entity Framework 6
https://docs.microsoft.com/ef/
Creative Commons Attribution 4.0 International
1.57k stars 1.94k forks source link

Please add examples #2326

Closed urig closed 4 years ago

urig commented 4 years ago

It is not easy to understand what the type of TColumns is and how to specify a column on which the UNIQUE constraint is to be applied.

It is even harder to understand how to apply the constraint to a combination two or more columns.

IMHO, this page would benefit from the addition of examples (of the above).

Tx, urig


Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

ajcvickers commented 4 years ago

@urig Can you elaborate a bit on why you are using CreateTableBuilder?

urig commented 4 years ago

@ajcvickers I'm trying to define a (composite) unique constraint on a table in an EF Core 3.1 Migration. I managed to find out how to do it courtesy of SO:

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.CreateTable(
        name: "Example",
        columns: table => new
        {
            Id = table.Column<Guid>(nullable: false),
            Foo = table.Column<string>(maxLength: 256, nullable: false),
            Bar = table.Column<string>(maxLength: 256, nullable: false)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_Example", x => x.Id);
            table.UniqueConstraint(
                name: "Unique_Foo", 
                columns: x => new {x.Foo, x.Bar}
            });
        }
}

I think it would be good if the official docs gave examples like the above for the bemefit of users.

roji commented 4 years ago

@urig users are typically not expected to write such migration code themselves - EF Core generates this code for them when dotnet ef migrations add is executed. While editing migrations is allowed and recommended in some cases, that is usually limited to adding raw SQL into migrations or possibly moving/changing certain blocks which EF Core already generated. Therefore we don't provide specific documentation on these APIs.

Do you have any particular reason you're writing migrations manually rather than having EF Core generate them?

smitpatel commented 4 years ago

On a different note, those are API docs rather than feature docs.

urig commented 4 years ago

@roji thank you for your response. I am trying to implement a business requirement using a UNIQUE constraint in the database. Seeing as my project is already using EF Migrations, it seems ideal to me to use it to define the constraint. I understand what you're saying about expectations from users but seeing as the API is public and fluent, I think users like me a tempted to use it and that's a good thing :)

@slimpater thanks, but what does that imply?

roji commented 4 years ago

@urig I think there may be some confusion here... The idea is indeed for users to use migrations to define unique constraints in the database. However, the way this is typically done in EF Core is to configure the constraint on your model, and then generate a migration out of that. EF Core will automatically inspect your model, compare it against a snapshot of the previous model, infer the changes and generate migrations to apply those changes. You are typically not supposed to manually write migration code yourself - except for some cases where EF Core can't generate what you want.

Please take a look at the model building docs, followed by the docs on migrations.

urig commented 4 years ago

@roji thanks. I understand what you're saying re: migrations now. At the same time, I think that since this API is public, it might as well be well-documented. I personally found it easier to use this API that to find the correct data annotations to define a composite unique constraint and other might too :)

roji commented 4 years ago

@urig just to make sure that you've seen the docs we have on unique indexes (include composite) and alternate keys - the former is what you should use to define a unique constraint in your model (unless it's being used as a foreign key in a relationship, in which case it's the latter). Does this documentation not seem sufficient?

There's a deeper point which I think you're missing. You need to define things on the model and not on migrations, since they may affect aspects of EF Core other than migrations; queries may actually get generated differently by EF Core based on this information.

Aside from that, the migration builder APIs are documented in our API docs. As it's discouraged to use these APIs directly in most regular scenarios, I don't think conceptual documentation for this is very relevant...

ajcvickers commented 4 years ago

@urig

I think that since this API is public, it might as well be well-documented.

I agree in principle. In practice, this documentation is far down the priority list because there is so much more value in fixing bugs, implementing features, and writing good documentation at the conceptual level and for many other APIs that are heavily used. As always, there is way more that we should do than we can do, so we have to prioritize.

urig commented 4 years ago

@roji @ajcvickers thank you kindly. Closing now.

urig commented 4 years ago

@roji @ajcvickers Ok so I've closed this but I have one thing that's still nagging me :)

The "Customize migration code" in the Migrations Overview official documentation gives a clear example of using the internal API. It was this example that led me down this path in the first place.

Would you agree that this does indicate that users are expected to use these APIs and that their documentation should be improved?

roji commented 4 years ago

@urig assuming you're referring to this section, note that it's showing how to introduce raw SQL into your migration - and not use the migration builder APIs (for the record nothing here is internal). In many cases you may need to supplement or the auto-generated calls, because EF Core cannot generate certain operations.

In other words, it's OK to edit your scaffolded migrations to do raw SQL - but as a general rule you shouldn't need to actually invoke the migration builder API, that's more for the scaffolded code.

urig commented 4 years ago

Alright. I understand that using the more implicit Data Annotations is a better option, especially as the model class becomes a "single source of truth". I still like the builder APIs a lot - they are such a nice OO take on DDL. :) Many thanks for clarifying. Much appreciated.