我有一个项目数组,我将其与更新的项目数组进行比较,以确定更改列的不同列表。它正在发挥作用。
但是我需要在那一行中构建两个对象,因为我需要将两个对象发送到我用来发送电子邮件的API。一个用于旧值,一个用于新值。我尝试过两种不同的方式:
var updates = currentRow.ItemArray
.Select((o, i) => new { Row = o, Index = i })
.Where(r => (r.Row == null && updatedRow[r.Index] != null)
|| (r.Row != null && updatedRow[r.Index] != null
&& !r.Row.Equals(updatedRow[r.Index])))
.Select(r => new AppServices.NotificationData[]
{
new AppServices.NotificationData
{
Key = string.Format("{0}OldValue",
columns[r.Index].ColumnName.EmailTemplateName(type)),
Value = Convert.ToString(currentRow[r.Index])
},
new AppServices.NotificationData
{
Key = string.Format("{0}NewValue",
columns[r.Index].ColumnName.EmailTemplateName(type)),
Value = Convert.ToString(updatedRow[r.Index])
}
});
但实际上,正如预期的那样,这个实际上给了我一个可枚举的数组。我也试过这样:
var updates = currentRow.ItemArray
.Select((o, i) => new { Row = o, Index = i })
.Where(r => (r.Row == null && updatedRow[r.Index] != null)
|| (r.Row != null && updatedRow[r.Index] != null
&& !r.Row.Equals(updatedRow[r.Index])))
.Select(r => new AppServices.NotificationData
{
Key = string.Format("{0}OldValue",
columns[r.Index].ColumnName.EmailTemplateName(type)),
Value = Convert.ToString(currentRow[r.Index])
})
.Select(r => new AppServices.NotificationData
{
Key = string.Format("{0}NewValue",
columns[r.Index].ColumnName.EmailTemplateName(type)),
Value = Convert.ToString(updatedRow[r.Index])
});
但问题是第二个Select
传递了NotificationData
对象中的上一个选择,因此r
实际上不是项目数组。
此处currentRow
和updatedRow
分别是代表新旧数据的DataRow
个对象。
我确信有办法让我得到的东西,我只是不知道如何。
那么,我如何获得一个Select
,它被构建为返回单个类型,返回同一个对象的两个实例,以便可枚举最终为IEnumerable<NotificationData>
?
答案 0 :(得分:6)
在第一个查询中使用SelectMany
代替Select
:
var updates = currentRow.ItemArray
.Select((o, i) => new { Row = o, Index = i })
.Where(r => (r.Row == null && updatedRow[r.Index] != null)
|| (r.Row != null && updatedRow[r.Index] != null
&& !r.Row.Equals(updatedRow[r.Index])))
.SelectMany(r => new AppServices.NotificationData[]
{
new AppServices.NotificationData
{
Key = string.Format("{0}OldValue",
columns[r.Index].ColumnName.EmailTemplateName(type)),
Value = Convert.ToString(currentRow[r.Index])
},
new AppServices.NotificationData
{
Key = string.Format("{0}NewValue",
columns[r.Index].ColumnName.EmailTemplateName(type)),
Value = Convert.ToString(updatedRow[r.Index])
}
});
它会将您的IEnumerable<IEnumerable<T>>
展平为IEnumerable<T>
。
答案 1 :(得分:0)
如果您想要的是每行创建两个对象,然后能够将这两个对象一起发送到您的API,那么我认为最好的方法是使用匿名类型。
var updates = currentRow.ItemArray
.Select((o, i) => new { Row = o, Index = i })
.Where(r => (r.Row == null && updatedRow[r.Index] != null)
|| (r.Row != null && updatedRow[r.Index] != null
&& !r.Row.Equals(updatedRow[r.Index])))
.Select(r => new {
NotificationForServiceA = new AppServices.NotificationData({
Key = string.Format("{0}OldValue",
columns[r.Index].ColumnName.EmailTemplateName(type)),
Value = Convert.ToString(currentRow[r.Index])
}),
NotificationForServiceB = new AppServices.NotificationData({
Key = string.Format("{0}NewValue",
columns[r.Index].ColumnName.EmailTemplateName(type)),
Value = Convert.ToString(updatedRow[r.Index])
})
});
然后你可以这样使用它:
var oneItem = updates.FirstOrDefault();
myApi(oneItem.NotificationForServiceA, oneItem.NotificationForServiceB);
如果您想要的是每行创建两个NotificationData并将它们合并/展平在一个可枚举的中,那么您应该使用SelectMany
来执行该操作。请参阅MarcinJuraszek的答案。