代码之家  ›  专栏  ›  技术社区  ›  Dener

使用EntityTpeConfiguration映射short[]

  •  0
  • Dener  · 技术社区  · 7 年前

    有人能解释一下我应该如何使用数组或基元值列表映射实体吗 EntityTypeConfiguration . 我有以下实体和枚举:

    public class PermissionForm
    {
       public int Id {get; set;}
    
       public string Name {get; set;}
    
       public PermissionItem[] Permissions {get; set;}
    }
    
    public enum PermissionItem : short
    {
       EDIT = 1,
       SHARE = 2,
       ADMIN = 3
    }
    

    | PermissionForm |
    | -------------- |
    | Id             |
    | Name           |
    
    |  PermissionForm_PermissionItems |
    | ------------------------------- |
    | PermissionFormId                |
    | PermissionItem_Value            |
    

    到目前为止,我得到了以下代码,但我认为它不太靠右:

    public PermissionForMap()
    {
        this.ToTable("PermissionForm").HasKey(p => p.Id);
    
        this.Property(p => p.Name).HasColumnName("Name").HasMaxLength(30);
        this.Map(map =>
        {
           map.ToTable("PermissionsFormPermissionItem");
           map.Requires(p => p.Id);
           map.Properties(p => p.PermissionItems);
        });
    }
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   Federico Dipuma    7 年前

    [Flags]

    支持场景的最有效方法是使用 Enum FlagsAttribute 在其上(这至少需要EntityFramework 5):

    public class PermissionForm
    {
       public int Id {get; set;}
    
       public string Name {get; set;}
    
       public PermissionItem Permissions {get; set;}
    }
    
    [Flags]
    public enum PermissionItem : short
    {
       EDIT = 1,
       SHARE = 2,
       ADMIN = 4 // note that each value must be a power of 2
    }
    

    不需要任何特定映射:

    public PermissionForMap()
    {
        this.ToTable("PermissionForm").HasKey(p => p.Id);
    
        this.Property(p => p.Name).HasColumnName("Name").HasMaxLength(30);
        this.Property(p => p.Permissions).HasColumnName("Permissions"); // this is redundant, it's just to replicate your behavior
    }
    

    & ( AND ) | ( OR ) , ^ ( XOR ) ~ (complement)

    这将简化模型,并避免使用另一个表(这也需要查询中的连接)。

    实例

    SHARE 许可:

    var query = _dbContext.PermissionForms.Where(p => p.PermissionItem & PermissionItem.SHARE > 0);
    

    如果使用EntityFramework 6.1+还可以使用内置方法 HasFlag :

    var query = _dbContext.PermissionForms.Where(p => p.PermissionItem.HasFlag(PermissionItem.SHARE));
    

    为实体设置多个权限:

    var permission = new PermissionForm
    {
        Name = "MyName",
        Permissions = PermissionItem.EDIT | PermissionItem. SHARE // this has EDIT and also SHARE
    };
    

    表映射

    如果您真的想将关系映射到一个表(在我看来,这对于您的场景来说是无用且低效的),那么您需要创建一个类,该类作为一个实体由EntityFramework支持:

    public class PermissionForm
    {
       public PermissionForm()
       {
           Permissions = new HashSet<PermissionEntity>();
       }
    
       public int Id {get; set;}
    
       public string Name {get; set;}
    
       public virtual ICollection<PermissionEntity> Permissions {get; set;}
    }
    
    public class PermissionEntity
    {
        public int PermissionFormId { get; set; }
    
        public PermissionItem PermissionItem { get; set; }
    
        public virtual PermissionForm PermissionForm { get; set; }
    }
    
    public enum PermissionItem : short
    {
       EDIT = 1,
       SHARE = 2,
       ADMIN = 3
    }
    

    并将其映射为模型的任何其他导航属性:

    public class PermissionForMap : EntityTypeConfiguration<PermissionForm>
    {
        public PermissionForMap()
        {
            this.ToTable("PermissionForm").HasKey(p => p.Id);
    
            this.Property(p => p.Name).HasColumnName("Name").HasMaxLength(30);
            this.HasMany(p => p.Permissions) 
                .WithRequired(e => e.PermissionForm)
                .HasForeignKey(e => e.PermissionFormId);
        }
    }
    
    public class PermissionEntityMap : EntityTypeConfiguration<PermissionEntity>
    {
        public PermissionEntityMap()
        {
            ToTable("PermissionEntities")
                .HasKey(e => new { e.PermissionFormId, e.PermissionItem }):
        }
    }