English 中文(简体)
Linq自连接和过滤器
原标题:Linq self-join and filter

我有一个<code>列表<;索赔事件>由此类组成:

public class ClaimEvent
{
    public ClaimEventType ClaimEventClaimEventType { get; set; }
    public DateTime OccurredOn { get; set; }
    public DateTime Created { get; set; }
    public DateTime Modified { get; set; }
    public string CreatedBy { get; set; }
    public string ModifiedBy { get; set; }
}

ClaimEventType是这样的。。。

public class ClaimEventType
{
    public ClaimEventType()
    {
        Cancels = new List<ClaimEventType>();
        CancelledBy = new List<ClaimEventType>();
    }

    public int ClaimEventTypeId { get; set; }
    public string ClaimEventTypeName { get; set; }
    public List<ClaimEventType> Cancels { get; set; }
    public List<ClaimEventType> CancelledBy { get; set; }
}

Cancels列出此事件在按OccuredOn排序的列表中出现在它们之后时取消的所有事件类型CancelledBy是相反的,也就是说,如果cancelled By

如何查询这些对象的列表,以便列表中其他项目取消的项目不会出现在结果中?

问题回答

非常简单,尽管您似乎在重复列出取消和取消的工作:

List<ClaimEvent> theList = new List<ClaimEvent>();

theList.RemoveAll(i => (from j in theList
                        where j.ClaimEventClaimEventType.Cancels.Contains(i.ClaimEventClaimEventType) &&
                        j.OccurredOn > i.OccurredOn
                        select j).Count() > 0);

如果集合中存在另一个ClaimEvent,该ClaimEvent取消了此元素类型的ClaimEvent并发生在此索赔事件之后(即,存在一个或多个此类元素的情况下),请从集合对象中删除所有元素。

编辑:具有更可读语法的功能等效代码

这也可以使用调用<code>Exists</code>中的第二个委托方法来查找任何取消事件:

theList.RemoveAll(i =>
    theList.Exists(j =>
        j.ClaimEventClaimEventType.Cancels.Contains(i.ClaimEventClaimEventType) &&
        j.OccurredOn > i.OccurredOn));

资源

MSDN:List(Of T).RemoveAll方法

如果我正确理解你的要求,我想你可能会想要这样的东西。它本质上是对序列进行迭代,并构建已经存在的事件类型的<code>HashSet</code>。对于序列中的每个ClaimEvent,它会检查先前存在的事件类型是否为当前对象的取消类型之一。如果找不到,则可以生成当前对象并将其类型添加到集合中。

public static IEnumerable<ClaimEvent> GetUncancelledEvents(this IEnumerable<ClaimEvent> source)
{   
    // note: override Equals & GetHashCode in ClaimEventType**
    HashSet<ClaimEventType> existingEventTypes = new HashSet<ClaimEventType>();

    foreach (var @event in source)
    {
        bool isCancelled = false;
        foreach (var cancellingEvent in @event.ClaimEventClaimEventType.CancelledBy)
        {
            if (existingEventTypes.Contains(cancellingEvent))
            {
                isCancelled = true;
                break;
            }
        }

        if (!isCancelled)
        {
            existingEventTypes.Add(@event.ClaimEventClaimEventType);
            yield return @event;
        }
    }
}

。。。

var uncancelledEvents = eventsList.GetUncancelledEvents();




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...