Efcore: Create a 'IsUnique' attribute

Created on 21 Oct 2020  路  11Comments  路  Source: dotnet/efcore


I would like to not need to type all of this just to set a few columns as unique in the database. This is just for one case, I have an entire set of 20 lines just to set unique constrains in my OnModelCreating method.
```c#
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity(company =>
{
company.HasIndex(x => x.IE).IsUnique();
company.HasIndex(x => x.IM).IsUnique();
company.HasIndex(x => x.CNPJ).IsUnique();
});
}


<!-- Describe the solution you'd like -->
Instead, why not create an `[Unique]` attribute to be used like this:

```c#
public class Company : Contact
{
    [Unique]
    [Required]
    [DataMember]
    public string CNPJ { get; set; }

    [Unique]
    [DataMember]
    public string? IE { get; set; }

    [Unique]
    [DataMember]
    public string? IM { get; set; }

    public Company() : base()
    {
        CNPJ = string.Empty;
    }
}

I don't believe this exists, given that I couldn't find any documentation that proved otherwise and also couldn't find any open issues on the matter. Please consider.

closed-question customer-reported

Most helpful comment

We discussed this some more and created two new issues to cover points raised here: #23153 and #23154.

All 11 comments

Checkout IndexAttribute which allows you to configure indexes and market them as unique. This feature requires using EF Core 5.0. Current pre-release version on nuget, 5.0-rc2 contains it.

Thanks @smitpatel that does the job, but isn't it possible to have a simpler attribute per property? Or was there a design decision that said otherwise?

@BrunoBlanes Is it your intention to create a unique constraint or a unique index in the database, or does it not matter to you which of these is created?

You got me there, they seem to me to do the same thing, but if I studied properly what I want is a unique constraint, which is to have a single value per cell on a specific column.

@BrunoBlanes Thanks. So, to ask my question in a slightly different way: the reason you don't want to use [Index] is not because you care about the (largely academic) difference between a constraint and an index? (I believe most databases will create a unique index to implement the unique constraint anyway.)

It is not.
And it is no that I don't want to use it either, in fact I am using it now that you've showed me the attribute, but I think it is easier to understand which properties a specific column has on the database just by looking at its property on the model class and seeing the attributes on top of it.
In other words, if you have a model with 10 properties you want to set a unique constraint to, your [Index] attribute would be about two lines long on top of a class. I think it makes more sense to add it on a per property basis, and not globally.

c# [Index(nameof(IE), nameof(IM), nameof(CNPJ), IsUnique = true)]
This is what I had to do in one case for 3 properties, if I could have set one [Unique] attribute on top of each one of those properties it would make more sense for what I need.

On side note,

[Index(nameof(IE), nameof(IM), nameof(CNPJ), IsUnique = true)]

Creates a unique index over all 3 properties (composite index). In order to define own separate unique index over each property following should be used

[Index(nameof(IE), IsUnique = true)]
[Index(nameof(IM), IsUnique = true)]
[Index(nameof(CNPL), IsUnique = true)]

Hum, that makes sense, I didn't read enough through the docs to see that, thanks @smitpatel.

We discussed this some more and created two new issues to cover points raised here: #23153 and #23154.

@ajcvickers thanks for considering.

Was this page helpful?
0 / 5 - 0 ratings