如何使用EF实施多级约束

时间:2019-02-01 13:16:53

标签: c# asp.net-mvc entity-framework-6

假设我有一个仓库->箱->零件(形状,大小,颜色)关系。我们可以轻松地在Part上具有唯一的索引约束,这将使我可以为每个Bin标记多个相同颜色的部分(例如,仅一个“ Red”)违反错误。但是,如果我希望有一个约束,使每个仓库只能有一个这样的零件怎么办?如何在EF中做到这一点?

1 个答案:

答案 0 :(得分:0)

因此,您的域实体类如下所示:

public enum ColorEnum : byte
{
    Red = 1,
    Blue = 2
}

public class Part
{
    public long Id { get; private set; }

    public ColorEnum Color { get; private set; }

    public Bin Bin { get; private set; }
    public int BinId { get; private set; }
}

public class Bin
{
    public int Id { get; private set; }

    public Warehouse Warehouse { get; private set; }
    public short WarehouseId { get; private set; }

    public ICollection<Part> Parts { get; private set; }
}

public class Warehouse
{
    public short Id { get; private set; }

    public ICollection<Bin> Bins { get; private set; }
}

由于您希望零件现在每个仓库都具有唯一的颜色,因此现在需要他们了解其Warehose。因此,在Part类中添加对Warehouse的引用:

public class Part
{
    public long Id { get; private set; }

    public ColorEnum Color { get; private set; }

    public Bin Bin { get; private set; }
    public int BinId { get; private set; }

    public Warehouse Warehouse { get; private set; }
    public short WarehouseId { get; private set; }
}

现在,我们要在Part类上为(WarehouseId,Color)创建唯一索引。

我们可以通过两种方式实现这一目标:

1)通过将注释添加到实体的属性(来自命名空间System.ComponentModel.DataAnnotations.Schema):

public class Part
{
    public long Id { get; private set; }

    [Index("UX_Warehouse_Color", 2, IsUnique = true)]
    public ColorEnum Color { get; private set; }

    public Bin Bin { get; private set; }
    public int BinId { get; private set; }

    public Warehouse Warehouse { get; private set; }
    [Index("UX_Warehouse_Color", 1, IsUnique = true)]
    public short WarehouseId { get; private set; }
}

2)通过在DbContext类实现中使用EntityFramework fluent API,在protected virtual void DbContext.OnModelCreating(DbModelBuilder modelBuilder);方法的替代中:

modelBuilder.Entity<Part>()
    .HasIndex(part => new { part.WarehouseId, part.Color })
    .IsUnique();