【问题标题】:How to join two tables using LINQ (using Query or method syntax) in Asp.Net Mvc project如何在 Asp.Net Mvc 项目中使用 LINQ(使用查询或方法语法)连接两个表
【发布时间】:2017-09-20 18:44:34
【问题描述】:

如何使用 LINQ(使用查询或方法语法)在我的选择选项中显示这些产品尚未出现在我的库存表中? 在此图像示例中,我只想显示服务器和打印机,因为它们不在我的库存表中。

我正在尝试这样做但不工作:

[HttpGet]
        public async Task<ActionResult> GetInventory()
        {
            using (db)
            {

              var inventory = from p in db.Product
              join I in db.Inventory on I.ProductId equals p.ProductId
              where I.ProductId != p.ProductId
              select new { 
              ProductId = p.ProductId, ProductName = p.ProductName };
              return inventory;

         }
}

我只能获得产品和库存,但当我加入它们时却不能...

public IQueryable<Product> GetProducts()
        {

            return db.Products;
        }

public IQueryable<Inventory> GetInventory()
        {

            return db.Inventories;
        }

public class InventoryViewModel
    {
    public int Inventory { get; set; }
    public int ProductId { get; set; }
    public int Quantity { get; set; }

    }

然后我有我的 Javascript 函数来检索

function Products() {
    $.ajax({
        type: "GET",
        url: "/Api/GetInventory",
        dataType: "json",
        success: function (result) {
            $.each(result, function (key, value) {
                $("#Products").append($("<option></option>").val(value.ProductId).html(value.ProductName));
            });
        }
    });

}

如何修改我的操作以使产品不在我的库存表中?谢谢。

【问题讨论】:

  • 你在这里混了很多东西,这就是为什么你没有得到任何回应。试着把你的问题分开。它看起来与 javascript 等没有任何关系。如果某些东西不起作用,请解释到底是什么不起作用

标签: javascript asp.net-mvc join left-join


【解决方案1】:

另一个我认为可能更快的仅 LINQ 解决方案如下:

var result = db.Product
                .Where(p => !db.Inventory
                        .Any(i => i.ProductId == p.ProductId))
                .Select(p => new 
                {
                    ProductId = p.ProductId,
                    ProductName = p.ProductName
                });

正如@Shyju 提到的,您应该使用以下命令将结果作为 json 返回:

return Json(result, JsonRequestBehavior.AllowGet);

这使得它成为完整的 sn-p:(如果不使用 .net 核心,您可能需要指定 JsonRequestBehavior.AllowGet

[HttpGet]
public async Task<IActionResult> GetInventory()
{
    var result = db.Product
                    .Where(p => !db.Inventory
                            .Any(i => i.ProductId == p.ProductId))
                    .Select(new 
                    {
                        ProductId = p.ProductId,
                        ProductName = p.ProductName
                    });
    return Json(result);
}

【讨论】:

  • 感谢您的回复。我没有收到错误,当我打开它时,产品没有显示在我的选项选择列表中。这是一个空列表,它在某处缺少某些东西......;)它看起来像一个列表,它很长但空......
  • 这可能是很多不同的事情(db 为空、选择失败、您没有正确填充下拉列表等)。在 Visual Studio 中,您能否在 return Json(result); 行上设置断点并将鼠标悬停在 result 变量上并查看它是否包含任何内容?随时发回调试窗口打开的屏幕截图的链接
  • 完美.. 我添加了 Select(a => new ProductViewModel with productId 和 ProductName .. 工作正常。谢谢
【解决方案2】:

从你的描述我只能猜测,但看起来你想建立一个"Excluding Join" in LINQ。我认为您将能够自己适应自己的表格。

【讨论】:

    【解决方案3】:

    您可以使用Contains 方法。

      var products = db.Products
                      .Where(x => db.Inventories
                                    .Select(f => f.Product).Contains(x.Id)==false)
                      .Select(a=>new { ProductId=a.ProductIId,
                                       ProductName = a.ProductName})
                      .ToList();      
    

    基本上,它从 Products 表中查询不存在于 Inventory 表中的项目,并将其转换为具有 ProductIdProductName 属性的匿名对象列表。

    如果您的代码位于 MVC 控制器中,则可以使用 Json 方法返回项目列表。如果那个action方法是GET类型,调用Json方法时需要显式使用JsonRequestBehavior.AllowGet枚举。

     return Json(products,JsonRequestBehavior.AllowGet);
    

    如果您的代码位于 Web api 控制器中,则无法将结果投影到匿名对象。因此,您可以跳过整个 Select 部分并返回 Product 对象。请记住,如果 Product 类具有其他属性(ProductIdProductName 除外),则这些属性将包含在此处的结果中。如果您只想发送这 2 个属性,则需要创建一个仅包含这 2 个属性的简单视图模型,并在投影部分中使用它。

    public class ProductVm
    {
        public int ProductId { set; get; }
        public string ProductName { set; get; }
    }
    
    [Route("api/GetInventory")]
    [HttpGet]
    public HttpResponseMessage  Get()
    {    
         var products = db.Products
                          .Where(x => db.Inventories
                                        .Select(f => f.Product).Contains(x.Id)==false)
                          .Select(a=>new ProductVm { ProductId=a.ProductIId,
                                                     ProductName = a.ProductName})
                          .ToList();     
        return Request.CreateResponse(HttpStatusCode.OK, products);
    
    }
    

    【讨论】:

    • 感谢您的回复,在我的 Api 操作中,我收到如下错误...。错误 CS1929 'IQueryable' 不包含“包含”的定义和最佳扩展方法重载'ParallelEnumerable.Contains(ParallelQuery, int)' 需要类型为 'ParallelQuery' 的接收器
    • 我尝试使用“IndexOf”而不是包含但几乎相同的错误消息
    • Contains methodSystem.Linq 中定义的扩展方法。只要你有一个 using 语句来导入它,它应该可以正常工作。
    • 我实际上在我的项目中使用了 System.Linq。但是我尝试了@Nbokmans 并进行了少量修改,它工作正常。我会感谢您的出色帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 2021-03-29
    • 1970-01-01
    • 1970-01-01
    • 2013-05-26
    • 1970-01-01
    相关资源
    最近更新 更多