【问题标题】:Join a SQL table with data from API using EF使用 EF 将来自 API 的数据加入 SQL 表
【发布时间】:2019-12-19 11:19:40
【问题描述】:

我有这个结构:

  • 笔记和其他数据表的 SQL 数据库(这似乎与这个问题无关)。 note 表引用了一张票。为此,我使用实体框架来加载数据。
  • 票证的 API 调用,为此我使用 C# 中的 HttpClient

现在我想使用 SQL 查询将这两个对象彼此连接起来,以查询笔记中的多个其他相关数据。

在 SQL 中,我知道你可以做这样的事情。将表声明为变量,插入一些数据并将其与注释连接起来。

declare @tickets table(
    ID int primary key, 
    [Subject] nvarchar(max)
);

-- Making API call and insert results into @tickets

select *
from Notes note inner join @tickets tick on tick.ID = note.TicketID
where tick.Subject like @q + '%';

我现在的问题是,我能否在 EF 中得到相同的结果?我知道我无法使用 EF 进行 API 调用,因此我在方法 TicketService.GetTicketsAsync() 中执行此操作。


我已经尝试了下面的代码,所以我也可以查询其他数据表。

TicketService ticketService = new TicketService();
IEnumerable<Ticket> tickets = await ticketService.GetTicketsAsync();

(await db.Notes
         .ToListAsync())
         .Join(
             tickets,
             note => note.TicketID,
             tick => tick.ID,
             (note, tick) =>
             {
                 note.Ticket = tick;
                 return note;
             }
         )
         .AsQueryable();

但这给了我这个错误:

IQueryable 没有实现 IDbAsyncEnumerable&lt;Note&gt;。只有实现 IDbAsyncEnumerable 的源才能用于实体框架异步操作。更多详情请见http://go.microsoft.com/fwlink/?LinkId=287068

我访问了该链接,但那里的示例使用了单元测试和模拟数据。就我而言,它不是测试代码和真实数据。

代码看起来也不高效,因为使用await db.Notes.ToListAsync() 会选择Notes 表中的所有内容。


使用这个db.Notes.Join(/* same arguments as second code block */) 会给我这个编译错误:

带有语句体的 lambda 表达式不能转换为表达式树。


使用如下代码的映射类

db.Notes
  .Join(
       tickets,
       note => note.TicketID,
       tick => tick.ID,
       (note, tick) => new Mapper() { Note = note, Ticket = tick }
  );

当我做.ToListAsync()时给出下一个错误:

无法创建Ticket 类型的常量值。此上下文仅支持原始类型或枚举类型。


要像第一个代码块一样编写我想要的完整查询似乎很难,因为我有很多选项可以查询。使用 EF 就容易多了。

【问题讨论】:

    标签: c# sql-server entity-framework linq inner-join


    【解决方案1】:

    从您的查询中删除分配,您就可以了。

    var list = db.Notes
         .Join(
             tickets,
             note => note.TicketID,
             tick => tick.ID,
             (note, tick) => new { note, tick}
    
         )
         .ToList();
         foreach(var item in list)
              item.note.Ticket = item.tick;
    

    您也可以创建一个new Note(),但您必须逐个属性地复制它。

    如果这是在 EF-Model 中建立的 Relation,则不需要最后一次迭代,也不需要整个 Join。

    应该很短

       db.Notes.Include(tickets)
    

    加载相同的内容,但按项目分组,这更常见且更有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-28
      • 2022-01-23
      • 2018-03-13
      • 2016-10-09
      • 1970-01-01
      • 2012-05-16
      • 2011-11-13
      • 1970-01-01
      相关资源
      最近更新 更多