[英]Does EF Core allow a unique column to contain multiple nulls?
My entity has a property which is allowed to be null.我的实体有一个允许为空的属性。 BUT, if it isn't null, then it must be unique.
但是,如果它不为空,那么它必须是唯一的。 In other words, the column is unique but allows multiple nulls.
换句话说,该列是唯一的,但允许多个空值。
I've tried:我试过了:
config.Property(p => p.ProductId).IsRequired(false);
I remember struggling to get this to work in pre-Core EF.我记得努力让它在 pre-Core EF 中工作。
Is this possible?这可能吗? How do I configure the entity?
如何配置实体?
Yes, you can do that with EF Core, as a Unique index by default is created as a filtered index (WHERE ... IS NOT NULL)是的,您可以使用 EF Core 做到这一点,因为默认情况下唯一索引是作为过滤索引创建的(WHERE ... IS NOT NULL)
config.Entity<Product>()
.HasIndex(b => b.ProductId)
.IsUnique();
https://github.com/aspnet/EntityFramework/pull/2868 https://github.com/aspnet/EntityFramework/pull/2868
I know this is old but, for those who find it now, the default behaviour I'm seeing in EF Core 5.0 is not what's described in the accepted answer.我知道这是旧的,但是对于那些现在找到它的人来说,我在 EF Core 5.0 中看到的默认行为与接受的答案中描述的不同。 You can specify a filter for an index explicitly and here's an example of one I just created:
您可以明确地为索引指定过滤器,这是我刚刚创建的一个示例:
modelBuilder.Entity<Reef>(etb =>
{
// ...
etb.HasIndex(r => r.Label)
.HasFilter("Label IS NOT NULL")
.IsUnique();
// ...
});
EDIT:编辑:
I think that I have worked out the complete answer.我想我已经找到了完整的答案。 If you have a property that is a nullable value type and you create a unique index on that then that index will have a filter by default.
如果您有一个可为空值类型的属性,并且您在该属性上创建了一个唯一索引,那么该索引将默认有一个过滤器。 If the property is a reference type though, you have to specify that it is nullable as an extra step, either using the fluent API or an attribute.
但是,如果该属性是引用类型,则必须使用 fluent API 或属性指定它可以为 null 作为额外步骤。 I haven't tested with an attribute but, using the fluent API, the resulting index will not have a filter by default.
我没有使用属性进行测试,但是,使用 fluent API,默认情况下生成的索引不会有过滤器。 Consider the following entity:
考虑以下实体:
public class Thing
{
public int ThingId { get; set; }
public string Text { get; set; }
public int? StuffId { get; set; }
public Stuff Stuff { get; set; }
}
With the following in the DbContext
:在
DbContext
有以下DbContext
:
modelBuilder.Entity<Thing>(etb =>
{
etb.Property(t => t.Text)
.IsRequired(false);
etb.HasIndex(t => t.Text)
.IsUnique();
etb.HasIndex(t => t.StuffId)
.IsUnique();
});
The unique index generated on the StuffId
column will have a filter by default while the one on Text
will not.默认情况下,在
StuffId
列上生成的唯一索引将有一个过滤器,而Text
则没有。 A filter must be specified explicitly for the Text
column index:必须为
Text
列索引明确指定过滤器:
modelBuilder.Entity<Thing>(etb =>
{
etb.Property(t => t.Text)
.IsRequired(false);
etb.HasIndex(t => t.Text)
.HasFilter("Text IS NOT NULL")
.IsUnique();
etb.HasIndex(t => t.StuffId)
.IsUnique();
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.