【问题标题】:Entity Framework: Join Entities of Different Types and Order by Date实体框架:加入不同类型的实体并按日期排序
【发布时间】:2013-01-06 05:06:33
【问题描述】:

我读过一些听起来很相似的文章,但我不太能理解所讨论的内容。我使用的是 C# Entity Framework Code First 和 MVC 4。这是一些分层模型的大纲。

 Project
      ProjectImage
      ProjectDoc
           Comment
                CommentVote
                CommentReply
                     CommentReplyVote

所有这些模型都有一个 DateCreated 字段。我想运行一个查询,我可以按日期排序,并在同一个列表中显示所有这些事件中最新到最旧的事件。我想以不同的方式处理(显示)每一个。我不知道从哪里开始,也不知道在 Stackoverflow 上使用什么搜索词来找到答案。

【问题讨论】:

  • 不是控制器事件。事件是它的创建时间,即 DateCreated 字段。因此,无论是正在创建的项目、评论投票、评论回复还是其他任何内容。
  • 好的...我明白了。我正在编写一些代码来向您展示我将如何处理这个问题。

标签: linq entity-framework ef-code-first


【解决方案1】:

这是我承诺的代码...

它不是最先进的,但它是一个简单的控制台应用程序,可让您了解如何处理此问题。我基本上是从列表中读取的(在您的情况下,您将从数据库表中读取)。然后我将DateCreated 和对象本身添加到一个自定义类中,该类允许通过DateCreated 字段对所有对象进行排序。演示代码由您决定,但我会根据对象类型向您展示如何打印到控制台。

class Program
{
    static void Main(string[] args)
    {
        var projects = new List<Project>{
        new Project() {  ProjectId = 1, ProjectName = "My Secret Project", DateCreated = DateTime.Today.AddHours(-1) },
        new Project() {  ProjectId = 2, ProjectName = "My Big Project", DateCreated = DateTime.Today.AddHours(-2) }};

        var projectImages = new List<ProjectImage> {
        new ProjectImage() {  ProjectImageId = 1, ProjectImageSize = 17.17, DateCreated = DateTime.Today.AddHours(-3) },
        new ProjectImage() {  ProjectImageId = 2, ProjectImageSize = 10.17, DateCreated = DateTime.Today.AddHours(-4) }};

        var objects = new List<MyCustomClass>();

        foreach (var project in projects)
        {
            objects .Add(
                new MyCustomClass() { DateCreated = project.DateCreated, Object = project });
        }

        foreach (var projectImage in projectImages)
        {
            objects.Add(
                new MyCustomClass() { DateCreated = projectImage.DateCreated, Object = projectImage });
        }

        // Objects ordered by Date, Newest first...
        var objectsByDateCreated = objects.OrderByDescending(o => o.DateCreated);

        foreach (var @object in objectsByDateCreated)
        {
            Console.WriteLine(string.Format("{0} => {1}", @object.Object.GetType().Name, @object.DateCreated));
        }

        // Displaying objects according to type
        foreach (var @object in objectsByDateCreated)
        {
            if (@object.Object is Project)
            {
                var project = @object.Object as Project;

                Console.WriteLine(project.ProjectName);
            }
            else if (@object.Object is ProjectImage)
            {
                var projectImage = @object.Object as ProjectImage;

                Console.WriteLine(projectImage.ProjectImageSize);
            }
        }
    }
}

public class MyCustomClass
{
    public DateTime DateCreated { get; set; }
    public object Object { get; set; }
}

public class Project
{
    public int ProjectId { get; set; }
    public string ProjectName { get; set; }
    public DateTime DateCreated { get; set; }
}

public class ProjectImage
{
    public int ProjectImageId { get; set; }
    public double ProjectImageSize { get; set; }
    public DateTime DateCreated { get; set; }
}

【讨论】:

  • 但是排序是在内存中处理的,问题具体说是 EF。
  • 从他的问题来看,在这种情况下,订单发生的位置并不重要。此外,我无法想象在数据库服务器端一次性处理所有这些的另一种方式...... :)
  • 我不太了解内存和EF之间的区别。这看起来正是我所需要的,一旦我有机会实现它,我会将答案标记为已接受。他们的缺点是“在记忆中做”吗?
  • @Jed:如果您没有“数百万”条记录,那么在内存中进行排序不会对性能造成重大影响。如果它是数千个,你就可以像我在这个简单的代码中向你展示的那样去做。正如您可能已经猜到的那样,主要缺点是性能。按照 ivowiblo 的建议执行 UNION 是一种困难的方法,因为数据集必须匹配(表模式 + 列数等)......我什至不知道这是否可能。当他在 EF 中说的时候,他的意思是在数据库服务器端进行排序(让服务器完成繁重的工作)。正如我所说,我没有设想一种方法......
  • 感谢一百万,稍作调整,这工作完美....现在添加其他 6 个操作!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-13
  • 1970-01-01
  • 2016-08-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多