如何将我的 Linq 查询转换为预期的 Web API return 类型

How to cast my Linq query to the expected Web API return type

我的 .Net Core Web API 调用不是 return 向浏览器输入值,而是挂起浏览器。

我有这些型号:

public class Status
    {
    public long StatusId { get; set; }
    public long UserId { get; set; }
    public string Body { get; set; }
    public virtual User User { get; set; }
    }

public class User
    {
    public long UserId { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public virtual ICollection<Status> Statuses { get; set; }
    }

我的 Status 控制器的 Get 函数如下所示:

[HttpGet]
public IEnumerable<Status> GetAll()
    {
    var rv =  _context.Statuses.ToList();
    return rv;
    }

当我获取 API 端点时,我得到了第一条记录,然后浏览器挂起(继续加载)并且其余数据永远不会通过。

进入我的代码,我看到 rv 正在填充所有记录,但是我们遇到了 UserStatuses 然后 Statuses 有的问题User 等等 - 循环引用。

好的,让我们在控制器中试试这个,这样我们就不会从 User:

得到 Statuses
var rv = _context.Statuses.Select(s => new
    {
    StatusId = s.StatusId,
    UserId = s.UserId,
    Body = s.Body,
    User = from u in _context.Users
           select new
               {
               UserId = u.UserId,
               Name = u.Name,
               Email = u.Email,
               }
    }

    ).ToList();

return rv;

问题是 rv 是匿名类型,我无法弄清楚如何将其成功键入 IEnumerable<Status> return 类型,即使它与模型(User 中缺失的 Statuses 除外)。还是我要更改 return 类型和什么?

您可以使用 dynamic 作为 return 类型,或者您可以创建自定义 class 来保存您需要的查询投影:

[HttpGet]
public dynamic GetAll()
{
  var rv = _context.Statuses.Select(s => new
  {
   StatusId = s.StatusId,
   UserId = s.UserId,
   Body = s.Body,
   User = from u in _context.Users
          select new
           {
           UserId = u.UserId,
           Name = u.Name,
           Email = u.Email,
           }
   }).ToList();

   return rv;    
}

你也可以 return a HttpResponseMessage :

public HttpResponseMessage Get()
{
  var rv = _context.Statuses.Select(s => new
  {
   StatusId = s.StatusId,
   UserId = s.UserId,
   Body = s.Body,
   User = from u in _context.Users
          select new
           {
           UserId = u.UserId,
           Name = u.Name,
           Email = u.Email,
           }
   }).ToList();


    return Request.CreateResponse(HttpStatusCode.OK, rv);
}

我建议您使用单独的 ViewModel/DTO class 从 API 控制器发送数据。示例:

public class StatusModel
    {
    public long StatusId { get; set; }
    public long UserId { get; set; }
    public string Body { get; set; }
    public virtual User User { get; set; }
    }

public class UserModel
    {
    public long UserId { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    }


public HttpResponseMessage Get()
{
  var result = _context.Statuses.Include(e => e.User).Select(e => new StatusModel
    {
    StatusId = e.StatusId,
    UserId = e.UserId,
    Body = e.Body,
    User = new UserModel 
            {
                UserId = e.User.UserId,
                Name = e.User.Name,
                Email = e.User.Email,
            }
    }).ToArray();

    return Request.CreateResponse(HttpStatusCode.OK, result);
}