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; }
}
}