6

我有这样的实体的第一个列表:

public partial class Networking :EntityBase
{

    public virtual int NetWorkingId
    {
        get;
        set;
    }

    public virtual string NetWorkingParam
    {
        get;
        set;
    }

    public virtual System.DateTime NetWorkingDate
    {
        get;
        set;
    }
}

我有第二个这样的实体列表:

public partial class PrivateNetwork :EntityBase
{
    public virtual int PrivateNetworkId
    {
        get;
        set;
    }

    public virtual int ContaId
    {
        get { return _contaId; }
        set
        {
            if (_contaId != value)
            {
                if (Contact != null && Contact.ContaId != value)
                {
                    Contact = null;
                }
                _contaId = value;
            }
        }
    }

    public virtual Nullable<System.DateTime> DateCreation
    {
        get;
        set;
    }
}

我想将这两个列表合二为一,并按日期对所有元素进行排序。

那可能吗 ?

4

6 回答 6

6

你可以这样做,虽然它不是很漂亮,但你最终会得到一个,IEnumerable<object>所以你必须在使用它之前检查每个项目的类型:

IEnumerable<object> sorted = myNetworkingList
    .Concat<object>(myPrivateNetworkList)
    .OrderBy(n => n is Networking
                 ? (DateTime?)((Networking)n).NetWorkingDate
                 : ((PrivateNetwork)n).DateCreation);

foreach (object either in sorted)
{
    if (either is Networking)
        // Networking; do something
    else
        // PrivateNetwork; do something else
}
于 2012-11-13T08:22:57.450 回答
5

使用多态可以很容易地解决这个问题;为这两个类使用一个公共基类或接口,它具有DateTime您要排序的属性。

例子:

public abstract class NetworkingBase : EntityBase
{
    public DateTime DateToSortOn { get; set; }
}

或者

public interface INetworking
{
    public DateTime DateToSortOn { get; set; }
}

然后让你的类派生自NetworkingBase或实现INetworking

public partial class Networking : NetworkingBase
{
    ...
}

public partial class PrivateNetwork : NetworkingBase
{
    ...
}

或者

public partial class Networking : EntityBase, INetworking
{
    ...
}

public partial class PrivateNetwork : EntityBase, INetworking
{
    ...
}

对结果集合执行 LINQUnionConcat然后执行。OrderBy

于 2012-11-13T08:20:58.410 回答
2

我应该早先问的是。. .

对它们进行排序后,您想做什么?

这个问题的答案可能会对潜在的解决方案产生重大影响。

如果答案类似于我需要显示日期列表,您只需要按顺序排列日期。如果是这样,那么您不需要合并这两个列表,您可以获取仅排序日期的序列并使用它,例如

var orderedDates = networks.Select(n => n.NetworkingDate)
                   .Union(privateNetworks.Select(n => n.DateCreation))
                   .OrderBy(date => date);

如果答案是我需要显示一个链接列表,显示链接到对象 Id 的日期,以及标识对象类型的内容,那么您可以使用匿名对象来摆脱与上述非常相似的事情。

var orderedDates = networks.Select(n => new {Date = n.NetworkingDate, Id = n.NetWorkingId, NetworkType = n.GetType().Name})
                   .Union(privateNetworks.Select(n => new {Date = n.DateCreation, Id = n.PrivateNetWorkingId, NetworkType = n.GetType().Name}))
                   .OrderBy(n => n.Date);

但是,如果答案是我需要向 10 个最旧的网络发送 Shutdown() 命令,那么您确实需要一个多态解决方案,其中您有一个可以调用Shutdown()方法的单一类型,它将解析为特定的Shutdown()方法您正在使用的类型。

仅当用户khillang 的答案对您不起作用时才使用的多态解决方案

从对另一个答案的评论

@BinaryWorrier我选择这个答案是因为我已经在数据库中有记录,所以如果我选择添加一个新接口,我将如何处理在添加接口之前已经存储的记录?

我发现很难相信您的 ORM 不允许您向实体类添加接口,并且不以某种方式标记该接口和/或其成员,因此 ORM 会忽略它们。

但是,假设您不能添加新的接口或基类,您仍然可以多态地执行此操作。

添加接口,添加一个实现每个网络类(Abstractor类)的接口的类,然后将网络类转换为Abstractor类,将它们添加到 aList<INetwork>并对该列表进行排序。

public interface INetwork
{
    DateTime? Date { get; }
}

public class PrivateNetworkAbstractor
    :INetwork
{
    private PrivateNetwork network;
    public PrivateNetworkAbstractor(PrivateNetwork network)
    {
        this.network = network;
    }
    public DateTime? Date
    {
        get { return network.DateCreation; }
    }
}

public class NetworkingAbstractor
    : INetwork
{
    private Networking networking;
    public NetworkingAbstractor(Networking networking)
    {
        this.networking = networking;
    }
    public DateTime? Date
    {
        get { return networking.NetWorkingDate; }
    }
}
...

public IEnumerable<INetwork> MergenSort(IEnumerable<Networking> generalNetWorks, IEnumerable<PrivateNetwork> privateNetWorks)
{
    return generalNetWorks.Select(n => new NetworkingAbstractor(n)).Cast<INetwork>()
    .Union(privateNetWorks.Select(n => new PrivateNetworkAbstractor(n)).Cast<INetwork>())
    .OrderBy(n=> n.Date);
}
于 2012-11-13T14:38:53.707 回答
1

创建一个具有日期并在两个类中实现的接口。之后排序很容易。

public interface INetwork
{
    DateTime? Date { get; }
}

public partial class Networking :EntityBase, INetwork
{
    public DateTime? Date
    {
        get { return NetWorkingDate; }
    }
}

public partial class PrivateNetwork :EntityBase, INetwork
{
    public DateTime? Date
    {
        get { return DateCreation; }
    }
}

var commonList = new List<INetwork>();
// Add instances of PrivateNetwork and Networking to the list

var orderedByDate = commonList.OrderBy(n => n.Date);
于 2012-11-13T08:23:53.800 回答
0

第一个解决方案是使用匿名类型

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

namespace Example1
{
    class Program
    {
        class Human
        {
            public string Name { get; set; }
            public string Hobby { get; set; }
            public DateTime DateOfBirth { get; set; }
        }
        class Animal
        {
            public string Name { get; set; }
            public string FavouriteFood { get; set; }
            public DateTime DateOfBirth { get; set; }
        }

        static void Main(string[] args)
        {
            var humans = new List<Human>
            {
                new Human
                {
                    Name = "Kate",
                    Hobby = "Fitness",
                    DateOfBirth = DateTime.Now.AddYears(-27),
                },
                new Human
                {
                    Name = "John",
                    Hobby = "Cars",
                    DateOfBirth = DateTime.Now.AddYears(-32),
                },
            };

            var animals = new List<Animal>
            {
                new Animal
                {
                    Name = "Fluffy",
                    FavouriteFood = "Grain",
                    DateOfBirth = DateTime.Now.AddYears(-2),
                },
                new Animal
                {
                    Name = "Bongo",
                    FavouriteFood = "Beef",
                    DateOfBirth = DateTime.Now.AddYears(-6),
                },
            };

            var customCollection = (from human in humans
                                    select new
                                        {
                                            Name = human.Name,
                                            Date = human.DateOfBirth,
                                        }
                                        ).Union(from animal in animals
                                                select new
                                                    {
                                                        Name = animal.Name,
                                                        Date = animal.DateOfBirth,
                                                    }).OrderBy(x => x.Date);


            foreach (dynamic customItem in customCollection)
                Console.WriteLine(String.Format("Date: {0}, Name: {1}",      customItem.Date, customItem.Name));

            Console.Read();
        }
    }
}

或没有匿名类型(创建的 CustomClass):

...
class CustomClass
        {
            public string Name { get; set; }
            public DateTime Date { get; set; }
        }
...
var customCollection = (from human in humans
                                    select new CustomClass
                                        {
                                            Name = human.Name,
                                            Date = human.DateOfBirth,
                                        }
                                        ).Union(from animal in animals
                                                select new CustomClass
                                                    {
                                                        Name = animal.Name,
                                                        Date = animal.DateOfBirth,
                                                    }).OrderBy(x => x.Date);


            foreach (CustomClass customItem in customCollection)
                Console.WriteLine(String.Format("Date: {0}, Name: {1}", customItem.Date, customItem.Name));

...
于 2012-11-14T19:14:28.883 回答
0

我只是添加了一个基类并将其分配为两个列表的类的父类。然后简单地做了 union 。它成功了

于 2015-07-24T06:11:20.853 回答