拆分枚举标志以在集合中创建不同项目的有效方法

trn*_*son 1 .net c# enums flags split

我有一个这样的集合:

IEnumerable<RecordToSend> recordsToSend;
Run Code Online (Sandbox Code Playgroud)

由以下几部分组成:

public class RecordToSend {
    public Guid ApplicationId { get; set; }
    public ScheduleTypes Schedule { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

和标志枚举:

[Flags]
public enum ScheduleTypes
{
    None = 0,
    Daily = 1,
    Weekly = 2,
    Monthly = 4
}
Run Code Online (Sandbox Code Playgroud)

假设我有以下集合,它基本上是使用实体框架查询从数据库中提取的:

| ApplicationId | Schedule |
| ABC123        | 7        |
| DEF456        | 3        |
Run Code Online (Sandbox Code Playgroud)

将枚举拆分为多个不同记录的有效方法是什么,从而导致这种情况(可以使用类RecordToSend或其他类型,甚至是动态的,如果有意义的话):

| ApplicationId | Schedule |
| ABC123        | 1        |
| ABC123        | 2        |
| ABC123        | 4        |
| DEF456        | 1        |
| DEF456        | 2        |
Run Code Online (Sandbox Code Playgroud)

请注意,ScheduleTypes枚举有一个 0 值标志,我想在结果中忽略它。

尽管我很想听听对不同方法性能的想法,但效率并不是最重要的。如果在我从数据库中提取集合时可以作为实体框架查询的一部分在一个步骤中执行此拆分,那就太好了。在应用程序中,我不需要枚举标志处于原始的多值状态。

juh*_*arr 5

这应该有效。

var results = records.SelectMany(
    r => Enum.GetValues(typeof(ScheduleTypes))
             .Cast<ScheduleTypes>()
             .Where(e => e != ScheduleTypes.None && r.Schedule.HasFlag(e))
             .Select(e => 
                 new RecordToSend
                 {
                     Guid = r.Guid, 
                     Schedule = e
                 }));
Run Code Online (Sandbox Code Playgroud)

基本上,对于每个记录,它都会循环遍历可能的枚举值(跳过 0 值)并检查是否Schedule具有该标志。Guid然后使用相同的枚举标志创建一个新记录。然后SelectMany将创建的记录集合展平。

请注意,如果records是 an,IQueryable则必须添加 a AsEnumerable,因为我怀疑这会转换为 SQL。