C# 使用EntityTpeConfiguration映射short[]
有人能解释一下我应该如何使用C# 使用EntityTpeConfiguration映射short[],c#,entity-framework,ef-fluent-api,C#,Entity Framework,Ef Fluent Api,有人能解释一下我应该如何使用EntityTypeConfiguration将一个实体映射为一个数组或一组基本值吗。我有以下实体和枚举: public class PermissionForm { public int Id {get; set;} public string Name {get; set;} public PermissionItem[] Permissions {get; set;} } public enum PermissionItem : shor
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);
});
}
带有[Flags]
支持场景的最有效方法是使用Enum
,其上有FlagsAttribute
(这至少需要EntityFramework 5):
不需要任何特定映射:
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
}
通过这种方式,您可以仅使用位运算符和来管理权限
这将简化您的模型并避免使用另一个表(这也需要查询中的联接)
例子
获取具有共享权限的所有实体:
var query = _dbContext.PermissionForms.Where(p => p.PermissionItem & PermissionItem.SHARE > 0);
如果您使用EntityFramework 6.1+还可以使用内置方法:
为实体设置多个权限:
var permission = new PermissionForm
{
Name = "MyName",
Permissions = PermissionItem.EDIT | PermissionItem. SHARE // this has EDIT and also SHARE
};
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
}
表映射
如果您真的想将关系映射到一个表(在我看来,这对于您的场景来说是无用且低效的),那么您需要创建一个类,EntityFramework支持该类作为一个实体:
var permission = new PermissionForm
{
Name = "MyName",
Permissions = PermissionItem.EDIT | PermissionItem. SHARE // this has EDIT and also SHARE
};
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
}
公共类许可证表单
{
公共许可证表格()
{
权限=新的HashSet();
}
公共int Id{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection权限{get;set;}
}
公共类许可实体
{
public int PermissionFormId{get;set;}
公共PermissionItem PermissionItem{get;set;}
公共虚拟权限表单权限表单{get;set;}
}
公共枚举权限项:短
{
编辑=1,
份额=2,
管理员=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 }):
}
}
公共类权限表单:EntityTypeConfiguration
{
公共许可证格式()
{
这个.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);
}
}
公共类PermissionEntityMap:EntityTypeConfiguration
{
公共许可证映射()
{
ToTable(“许可实体”)
.HasKey(e=>new{e.PermissionFormId,e.PermissionItem}):
}
}
Enum与[标志]
支持场景的最有效方法是使用Enum
,其上有FlagsAttribute
(这至少需要EntityFramework 5):
不需要任何特定映射:
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
}
通过这种方式,您可以仅使用位运算符和来管理权限
这将简化您的模型并避免使用另一个表(这也需要查询中的联接)
例子
获取具有共享权限的所有实体:
var query = _dbContext.PermissionForms.Where(p => p.PermissionItem & PermissionItem.SHARE > 0);
如果您使用EntityFramework 6.1+还可以使用内置方法:
为实体设置多个权限:
var permission = new PermissionForm
{
Name = "MyName",
Permissions = PermissionItem.EDIT | PermissionItem. SHARE // this has EDIT and also SHARE
};
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
}
表映射
如果您真的想将关系映射到一个表(在我看来,这对于您的场景来说是无用且低效的),那么您需要创建一个类,EntityFramework支持该类作为一个实体:
var permission = new PermissionForm
{
Name = "MyName",
Permissions = PermissionItem.EDIT | PermissionItem. SHARE // this has EDIT and also SHARE
};
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
}
公共类许可证表单
{
公共许可证表格()
{
权限=新的HashSet();
}
公共int Id{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection权限{get;set;}
}
公共类许可实体
{
public int PermissionFormId{get;set;}
公共PermissionItem PermissionItem{get;set;}
公共虚拟权限表单权限表单{get;set;}
}
公共枚举权限项:短
{
编辑=1,
份额=2,
管理员=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 }):
}
}
公共类权限表单:EntityTypeConfiguration
{
公共许可证格式()
{
这个.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);
}
}
公共类PermissionEntityMap:EntityTypeConfiguration
{
公共许可证映射()
{
ToTable(“许可实体”)
.HasKey(e=>new{e.PermissionFormId,e.PermissionItem}):
}
}
为什么不直接从实体中删除阵列?您可以始终使用位操作获取和设置多个属性。从6.X开始,EF就支持这一点,同时也将避免使用联接。您是否仍使用EF4?更高版本(5,如果内存可用)增加了枚举支持。@FedericoDipuma噢,谢谢你,我不知道这一点。第一次使用这个EF。把你的答案写在那里,把它标记为正确的。但即使如此,我还是想知道如何进行映射。为什么不直接从实体中删除数组呢?您可以始终使用位操作获取和设置多个属性。从6.X开始,EF就支持这一点,同时也将避免使用联接。您是否仍使用EF4?更高版本(5,如果内存可用)增加了枚举支持。@FedericoDipuma噢,谢谢你,我不知道这一点。第一次使用这个EF。把你的答案写在那里,把它标记为正确的。但即使如此,我还是想知道如何进行映射。当然,所有这些都是基于OP能够升级其EF版本的假设。也许您可以(在已经非常完整的答案中)添加标记的枚举可以通过HasFlags
查询。明白!所以我不能直接映射一个基元数组,对吗?但真的谢谢,我用的是国旗。这很容易,而且很干净。太棒了@GertArnold谢谢,只是根据你的建议编辑了答案。当然,所有这些都是在假设的前提下