Entity Framework Left Join 我在使用时遇到的错误

发布于 2025-01-11 13:02:30 字数 979 浏览 2 评论 0原文

我正在编写一个查询,想要获取一个列表中的内容以及另一个列表中的内容,但遇到了此错误。

输入图片描述在这里

我的代码在这里,当我输入 join 而不是 left join 时,它工作正常,但我想要的值没有出现,请帮助:D

 var orgRolOlanDuyurular = _context.DuyuruOrgRol.Include(x=>x.Duyuru).ThenInclude(l => l.KL_DuyuruTur).Where(l => l.Duyuru.AktifMi);
 var tumDuyurular = _context.Duyuru.Include(l => l.KL_DuyuruTur).Where(l => l.AktifMi);
 var c = tumDuyurular.LeftJoin(orgRolOlanDuyurular,
                                tmDuyurular => tmDuyurular.Id,
                                orgOlanDuyurular => orgOlanDuyurular.DuyuruId,
                                (tmDuyurular, orgOlanDuyurular) => new DuyuruPaging{Id = tmDuyurular.Id, BaslangicTarihi = tmDuyurular.BaslangicTarihi, BitisTarihi = tmDuyurular.BitisTarihi, DuyuruTurAd = tmDuyurular.KL_DuyuruTur.Ad, Konu = tmDuyurular.Konu });

I was writing a query that I want to get what's in one of my lists and what's in the other, and I encountered this error.

enter image description here

My code is here, when I type join instead of left join, it works fine, but the value I want is not coming, please help :D

 var orgRolOlanDuyurular = _context.DuyuruOrgRol.Include(x=>x.Duyuru).ThenInclude(l => l.KL_DuyuruTur).Where(l => l.Duyuru.AktifMi);
 var tumDuyurular = _context.Duyuru.Include(l => l.KL_DuyuruTur).Where(l => l.AktifMi);
 var c = tumDuyurular.LeftJoin(orgRolOlanDuyurular,
                                tmDuyurular => tmDuyurular.Id,
                                orgOlanDuyurular => orgOlanDuyurular.DuyuruId,
                                (tmDuyurular, orgOlanDuyurular) => new DuyuruPaging{Id = tmDuyurular.Id, BaslangicTarihi = tmDuyurular.BaslangicTarihi, BitisTarihi = tmDuyurular.BitisTarihi, DuyuruTurAd = tmDuyurular.KL_DuyuruTur.Ad, Konu = tmDuyurular.Konu });

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小糖芽 2025-01-18 13:02:30

左外连接是一种连接,其中第一个集合的每个元素都会被返回,而不管它在第二个集合中是否有任何相关元素。您可以使用 LINQ 通过对组联接的结果调用 DefaultIfEmpty 方法来执行左外联接。

没有与 T-SQL 完全相同的语法来使用左连接或右连接。但是,您可以利用类似的方法。

假设您有两个实体。 SalesOrderDetailProduct

public partial class SalesOrderDetail
{
    public int SalesOrderID { get; set; }
    public short OrderQty { get; set; }
    public int ProductID { get; set; }
    public decimal UnitPrice { get; set; }
    public decimal LineTotal { get; set; }
    public override string ToString()
    {
        StringBuilder sb = new StringBuilder(1024);

        sb.AppendLine($"Order ID: {SalesOrderID}");
        sb.Append($"   Product ID: {ProductID}");
        sb.AppendLine($"   Qty: {OrderQty}");
        sb.Append($"   Unit Price: {UnitPrice:c}");
        sb.AppendLine($"   Total: {LineTotal:c}");

        return sb.ToString();
    }
}

和 Product 如下:

public partial class Product
{
    public int ProductID { get; set; }
    public string Name { get; set; }
    public string Color { get; set; }
    public decimal StandardCost { get; set; }
    public decimal ListPrice { get; set; }
    public string Size { get; set; }

    // Calculated Properties
    public int? NameLength { get; set; }
    public decimal? TotalSales { get; set; }
    public override string ToString()
    {
        StringBuilder sb = new StringBuilder(1024);

        sb.Append(Name);
        sb.AppendLine($"  ID: {ProductID}");
        sb.Append($"   Color: {Color}");
        sb.AppendLine($"   Size: {(Size ?? "n/a")}");
        sb.Append($"   Cost: {StandardCost:c}");
        sb.Append($"   Price: {ListPrice:c}");
        if (NameLength.HasValue)
        {
            sb.AppendLine($"   Name Length: {NameLength}");
        }
        if (TotalSales.HasValue)
        {
            sb.AppendLine($"   Total Sales: {TotalSales:c}");
        }
        return sb.ToString();
    }
}

现在使用 DefaultIfEmpty() 和 SelectMany() 在 Products 和 Sales 之间执行左连接,如下所示:

var query = (from prod in Products
         join sale in Sales
         on prod.ProductID equals sale.ProductID
           into sales
         from sale in sales.DefaultIfEmpty()
         select new
         {
             prod.ProductID,
             prod.Name,
             prod.Color,
             prod.StandardCost,
             prod.ListPrice,
             prod.Size,
             sale?.SalesOrderID,
             sale?.OrderQty,
             sale?.UnitPrice,
             sale?.LineTotal
         }).OrderBy(ps => ps.Name);

如果您希望使用方法语法,您可以按照以下代码获得相同的结果:

var query = Products.SelectMany(
          sale =>
          Sales.Where(s => sale.ProductID == s.ProductID).DefaultIfEmpty(),
          (prod, sale) => new
          {
              prod.ProductID,
              prod.Name,
              prod.Color,
              prod.StandardCost,
              prod.ListPrice,
              prod.Size,
              sale?.SalesOrderID,
              sale?.OrderQty,
              sale?.UnitPrice,
              sale?.LineTotal
          }).OrderBy(ps => ps.Name);

现在您可以使用简单的 foreach 循环,如下所示:

foreach (var item in query)
{
    count++;
    sb.AppendLine($"Product Name: {item.Name} ({item.ProductID})");
    sb.AppendLine($"  Order ID: {item.SalesOrderID}");
    sb.AppendLine($"  Size: {item.Size}");
    sb.AppendLine($"  Order Qty: {item.OrderQty}");
    sb.AppendLine($"  Total: {item.LineTotal:c}");
}

有关更多信息,您可以访问 https://learn.microsoft.com/en-我们/dotnet/csharp/linq/perform-left-outer-joins

A left outer join is a join in which each element of the first collection is returned, regardless of whether it has any correlated elements in the second collection. You can use LINQ to perform a left outer join by calling the DefaultIfEmpty method on the results of a group join.

There is no such syntax exactly the same as T-SQL to use Left or Right joins. However, there is a similar approach that you can leverage.

Assuming that you have two Entities. SalesOrderDetail and Product:

public partial class SalesOrderDetail
{
    public int SalesOrderID { get; set; }
    public short OrderQty { get; set; }
    public int ProductID { get; set; }
    public decimal UnitPrice { get; set; }
    public decimal LineTotal { get; set; }
    public override string ToString()
    {
        StringBuilder sb = new StringBuilder(1024);

        sb.AppendLine(
quot;Order ID: {SalesOrderID}");
        sb.Append(
quot;   Product ID: {ProductID}");
        sb.AppendLine(
quot;   Qty: {OrderQty}");
        sb.Append(
quot;   Unit Price: {UnitPrice:c}");
        sb.AppendLine(
quot;   Total: {LineTotal:c}");

        return sb.ToString();
    }
}

And Product as per below:

public partial class Product
{
    public int ProductID { get; set; }
    public string Name { get; set; }
    public string Color { get; set; }
    public decimal StandardCost { get; set; }
    public decimal ListPrice { get; set; }
    public string Size { get; set; }

    // Calculated Properties
    public int? NameLength { get; set; }
    public decimal? TotalSales { get; set; }
    public override string ToString()
    {
        StringBuilder sb = new StringBuilder(1024);

        sb.Append(Name);
        sb.AppendLine(
quot;  ID: {ProductID}");
        sb.Append(
quot;   Color: {Color}");
        sb.AppendLine(
quot;   Size: {(Size ?? "n/a")}");
        sb.Append(
quot;   Cost: {StandardCost:c}");
        sb.Append(
quot;   Price: {ListPrice:c}");
        if (NameLength.HasValue)
        {
            sb.AppendLine(
quot;   Name Length: {NameLength}");
        }
        if (TotalSales.HasValue)
        {
            sb.AppendLine(
quot;   Total Sales: {TotalSales:c}");
        }
        return sb.ToString();
    }
}

Now Perform a left join between Products and Sales using DefaultIfEmpty() and SelectMany() as per below:

var query = (from prod in Products
         join sale in Sales
         on prod.ProductID equals sale.ProductID
           into sales
         from sale in sales.DefaultIfEmpty()
         select new
         {
             prod.ProductID,
             prod.Name,
             prod.Color,
             prod.StandardCost,
             prod.ListPrice,
             prod.Size,
             sale?.SalesOrderID,
             sale?.OrderQty,
             sale?.UnitPrice,
             sale?.LineTotal
         }).OrderBy(ps => ps.Name);

If you wish to use method syntax, you can achieve the same result as per below code:

var query = Products.SelectMany(
          sale =>
          Sales.Where(s => sale.ProductID == s.ProductID).DefaultIfEmpty(),
          (prod, sale) => new
          {
              prod.ProductID,
              prod.Name,
              prod.Color,
              prod.StandardCost,
              prod.ListPrice,
              prod.Size,
              sale?.SalesOrderID,
              sale?.OrderQty,
              sale?.UnitPrice,
              sale?.LineTotal
          }).OrderBy(ps => ps.Name);

Now you can use a simple foreach loop as per below:

foreach (var item in query)
{
    count++;
    sb.AppendLine(
quot;Product Name: {item.Name} ({item.ProductID})");
    sb.AppendLine(
quot;  Order ID: {item.SalesOrderID}");
    sb.AppendLine(
quot;  Size: {item.Size}");
    sb.AppendLine(
quot;  Order Qty: {item.OrderQty}");
    sb.AppendLine(
quot;  Total: {item.LineTotal:c}");
}

For more information, you can visit https://learn.microsoft.com/en-us/dotnet/csharp/linq/perform-left-outer-joins

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文