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

C# 拆分枚举标志以在集合中创建不同项的有效方法,c#,.net,enums,split,flags,C#,.net,Enums,Split,Flags,我有这样的收藏: IEnumerable<RecordToSend> recordsToSend; 和标志枚举: [Flags] public enum ScheduleTypes { None = 0, Daily = 1, Weekly = 2, Monthly = 4 } 假设我有以下集合,它基本上是使用实体框架查询从数据库中提取出来的: | ApplicationId | Schedule | | ABC123 | 7

我有这样的收藏:

IEnumerable<RecordToSend> recordsToSend;
和标志枚举:

[Flags]
public enum ScheduleTypes
{
    None = 0,
    Daily = 1,
    Weekly = 2,
    Monthly = 4
}

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

| ApplicationId | Schedule |
| ABC123        | 7        |
| DEF456        | 3        |
将枚举拆分为多个不同记录的有效方法是什么(可以使用
RecordToSend
类,或者其他类型,如果有意义,甚至是动态的):


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

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

这应该可以

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
                 }));
var results=records.SelectMany(
r=>Enum.GetValues(typeof(ScheduleTypes))
.Cast()
.Where(e=>e!=ScheduleTypes.None&&r.Schedule.HasFlag(e))
.选择(e=>
新唱片发行
{
Guid=r.Guid,
附表=e
}));
基本上,对于每个记录,它循环遍历可能的枚举值(跳过0值),并检查
Schedule
是否具有该标志。然后使用相同的
Guid
和枚举标志创建一个新记录。
SelectMany
然后展平创建的记录集合

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

试试linq

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication1
{
    class Program
    {

        static void Main(string[] args)
        {
            IEnumerable<RecordToSend> recordsToSend = new List<RecordToSend>() {
                new RecordToSend() { ApplicationId = System.Guid.Parse("00000001-0001-0001-0001-000000000123"), Schedule = ScheduleTypes.Daily},
                new RecordToSend() { ApplicationId = System.Guid.Parse("00000001-0001-0001-0001-000000000123"), Schedule = ScheduleTypes.Weekly},
                new RecordToSend() { ApplicationId = System.Guid.Parse("00000001-0001-0001-0001-000000000123"), Schedule = ScheduleTypes.Monthly},
                new RecordToSend() { ApplicationId = System.Guid.Parse("00000001-0001-0001-0001-000000000456"), Schedule = ScheduleTypes.Daily},
                new RecordToSend() { ApplicationId = System.Guid.Parse("00000001-0001-0001-0001-000000000456"), Schedule = ScheduleTypes.Weekly}
            };

            var results = recordsToSend.AsEnumerable()
                .GroupBy(x => x.ApplicationId)
                .Select(x => new {
                    ApplicationID = x.Key, 
                    Schedule = x.Select(y => (int)y.Schedule).Sum()
                 }).ToList();

        }
    }
    [Flags]
    public enum ScheduleTypes
    {
        None = 0,
        Daily = 1,
        Weekly = 2,
        Monthly = 4
    }
    public class RecordToSend
    {
        public Guid ApplicationId { get; set; }
        public ScheduleTypes Schedule { get; set; }
    }
}
​
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统数据;
命名空间控制台应用程序1
{
班级计划
{
静态void Main(字符串[]参数)
{
IEnumerable recordsToSend=新列表(){
new RecordToSend(){ApplicationId=System.Guid.Parse(“00000001-0001-0001-0001-000000000 123”),Schedule=ScheduleTypes.Daily},
new RecordToSend(){ApplicationId=System.Guid.Parse(“00000001-0001-0001-0001-000000000 123”),Schedule=ScheduleTypes.Weekly},
new RecordToSend(){ApplicationId=System.Guid.Parse(“00000001-0001-0001-0001-000000000 123”),Schedule=ScheduleTypes.Monthly},
new RecordToSend(){ApplicationId=System.Guid.Parse(“00000001-0001-0001-0001-000000000 456”),Schedule=ScheduleTypes.Daily},
new RecordToSend(){ApplicationId=System.Guid.Parse(“00000001-0001-0001-0001-000000000 456”),Schedule=ScheduleTypes.Weekly}
};
var results=recordsToSend.AsEnumerable()
.GroupBy(x=>x.ApplicationId)
.选择(x=>new{
ApplicationID=x.键,
Schedule=x.Select(y=>(int)y.Schedule).Sum()
}).ToList();
}
}
[旗帜]
公共枚举计划类型
{
无=0,
每日=1,
每周=2,
每月=4
}
公共类RecordToSend
{
公共Guid应用程序ID{get;set;}
公共调度类型调度{get;set;}
}
}
​

太棒了,谢谢!我会试试这个,然后回来汇报。基本上正是我所寻找的,听起来像,但不确定要深入研究的高级概念。再次感谢您的帮助!这基本上正是我所需要的。我确实需要进行一些转换,以使其与我的代码实际工作(不确定这是否特定于我的代码),因此我建议在此处进行编辑,如果有意义,您可以接受。您是正确的
Enum.GetValues
返回一个
数组
,您需要强制转换这些值。我通过在它后面添加
Cast()
来修复这个问题。这是组合,而不是分离。
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
                 }));
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication1
{
    class Program
    {

        static void Main(string[] args)
        {
            IEnumerable<RecordToSend> recordsToSend = new List<RecordToSend>() {
                new RecordToSend() { ApplicationId = System.Guid.Parse("00000001-0001-0001-0001-000000000123"), Schedule = ScheduleTypes.Daily},
                new RecordToSend() { ApplicationId = System.Guid.Parse("00000001-0001-0001-0001-000000000123"), Schedule = ScheduleTypes.Weekly},
                new RecordToSend() { ApplicationId = System.Guid.Parse("00000001-0001-0001-0001-000000000123"), Schedule = ScheduleTypes.Monthly},
                new RecordToSend() { ApplicationId = System.Guid.Parse("00000001-0001-0001-0001-000000000456"), Schedule = ScheduleTypes.Daily},
                new RecordToSend() { ApplicationId = System.Guid.Parse("00000001-0001-0001-0001-000000000456"), Schedule = ScheduleTypes.Weekly}
            };

            var results = recordsToSend.AsEnumerable()
                .GroupBy(x => x.ApplicationId)
                .Select(x => new {
                    ApplicationID = x.Key, 
                    Schedule = x.Select(y => (int)y.Schedule).Sum()
                 }).ToList();

        }
    }
    [Flags]
    public enum ScheduleTypes
    {
        None = 0,
        Daily = 1,
        Weekly = 2,
        Monthly = 4
    }
    public class RecordToSend
    {
        public Guid ApplicationId { get; set; }
        public ScheduleTypes Schedule { get; set; }
    }
}
​