Linq创建类型化结果列表

本文关键字:列表 结果 类型化 创建 Linq | 更新日期: 2023-09-27 18:12:16

我已经做了一些努力,我想可能有图书馆可以使这项工作。例如,我为。net EF 6创建了一个映射到Sql Server表的模型类:

class Author {
   public long Id { get; set; }
   public string Name { get; set; }
}
class Book {
   public long Id { get; set; }
   public string Name { get; set; }
   public long AuthorId { get; set;}
}

有继承类:

class BookEx : Book {
   public string AuthorName { get;set; }
}

and LINQ query:

   var query = from t in context.Books
      join t1 in context.Authors on t.Id equals t1.AuthorId
      select new BookEx {
         Id = t.Id,
         Name = t.Name,
         AuthorId = t.AuthorId,
         AuthorName = t1.Name
      }

every认为工作得很好,但这是一个简单的类,当我需要像Book这样的类具有更多属性时,我需要填充每个属性,有时这太难了:

  select new BookEx {
     Id = t.Id,
     Name = t.Name,
     AuthorId = t.AuthorId,
     AuthorName = t1.Name
  }

我可以做一个简短的填充吗?

  select new BookEx {
     AuthorName = t1.Name
  }

父类Book的属性将由LINQ或其他方法填充?是否有库可以使这项工作变得困难(有时我们会忘记填充某些属性)?

EDITED:项目不使用关联。不需要使用关联,获取Author的全表(表中可以有10-40个属性)数据,但只获取Name属性。需要解决的问题,如在例子中

Linq创建类型化结果列表

我认为没有必要创建一个名为BookEx的新实体,您可以使用导航属性访问Author实体的详细信息,如AuthorName。您不需要使用select语句。例如:

 var books = from t in context.Books
      join t1 in context.Authors on t.Id equals t1.AuthorId;

这将返回书的详细信息与作者的详细信息,所以你可以得到这样的AuthorName -

foreach(var item in books)
{
    string authorName=item.Author.Name;
}
To achieve this you need to add one more property (navigation property to Author) in your book class:
public class Book {
   public long Id { get; set; }
   public string Name { get; set; }
   public long AuthorId { get; set;}
   public virtual Author Author { get; set; }
}

如果性能是最重要的关注点,那么您可能不得不失去一些灵活性,但是您不应该牺牲重用性。目前还不清楚您的盈亏平衡在哪里,但是如果您创建BookEx投影的方法适合您,那么您当然可以将其包装在一个方法中以供重用。这样就避免了"需要填充每个属性"answers"有时……"忘记填充某些属性":

static class DaoExtensions 
{
  public static IQueryable<BookEx> BookPlusAuthorNames(this DbContext context) 
  {
    var query = from t in context.Books
      join t1 in context.Authors on t.Id equals t1.AuthorId
      select new BookEx {
         Id = t.Id,
         Name = t.Name,
         AuthorId = t.AuthorId,
         AuthorName = t1.Name
      }
    return query;
  }        
}

再一次,因为你的性能问题,我不会去外部库解决这个问题,如前所述。


对于后代:如果开发灵活性优先于性能,那么最好通过在Book上添加Author作为导航属性来映射这种自然关联:

class Book {
    ...
    [ForeignKey("AuthorId")]
    public virtual Author Author { get; set; }
}

这将允许像book.Author.Name这样的用法直接导航到Name。EF将处理所有连接逻辑