【问题标题】:How to approach querying a parent table based on values in a child table and a child tables related data table? [closed]如何根据子表和子表相关数据表中的值查询父表? [关闭]
【发布时间】:2018-08-03 18:08:20
【问题描述】:

上下文:我有一个父表(Product)、一个子表(Transactions)和一个子数据表(RelatedData)。

一个产品有很多交易。 'A' 类型的交易有一个带有 SpecialData 的相关数据条目。

我想获取所有 LAST 交易类型为“A”且 SpecialData 值为“B”的产品记录

我在 MSSQL 数据库上使用 linq to SQL。

var data = from p in db.Product
           select p;

//various filters
    data = data.Where(...);

我现在想要实现的查询有什么:

data = data.Where(p=> p.Transactions
                            .Where(t => p.ProductID == t.ProductID && 
                                        t.TransType == 'A') 
                            .OrderByDescending(t => t.DateTime)
                            .FirstOrDefault(t => t.RelatedData //Get latest
                                                     .Single().SpecialData == 'B')
                        != null
                    );

它没有返回我在数据库中设置的任何测试数据。请帮忙。

【问题讨论】:

  • 你不需要加入吗?
  • 那么,您是否尝试过简化任何查询并对其进行调试?找出返回的位置和数据并从那里开始?
  • 将其拆分为多个查询,并检查您在哪一步过滤掉不应过滤掉的内容
  • 如果在 LINQ 中过于复杂,请尝试编写存储过程以获得所需的结果。
  • @RyanWilson ORM 不需要连接,它们从实体关系生成连接语句。这些实体通过Transactions 集合相关联。这意味着p.ProductID == t.ProductID 是毫无意义的顺便说一句

标签: c# sql sql-server database linq


【解决方案1】:

你的目标是:

我想获取所有具有 LAST 的产品记录 类型为“A”且 SpecialData 值为“B”的事务

根据您的要求,我了解到关键是找到每个产品的最后一笔交易。

假设你的实体是这样的:

public class Product
    {
        public virtual ICollection<Transaction> Transactions { get; set; }
    }

    public class Transaction
    {
        public int TransId { get; set; }
        public int ProductId { get; set; }
        public Product Product { get; set; }

        public string TransType { get; set; }
        public DateTime DateTime { get; set; }

        public virtual RelatedData RelatedData  { get;set;}
    }

    public class RelatedData
    {
        public int TransId { get; set; }
        public virtual Transaction Transaction { get; set; }
        public string SpecialData { get; set; }

    }

事务和相关数据之间是一对一的关系。

你可以这样做:

  //last transaction for each product
            var transactions = db.Transactions.GroupBy(x =>x.Product)
                .SelectMany(a =>a.Where(b=>b.DateTime==a.Max(c=>c.DateTime)));
            //last transaction of TransType A
            var transA = transactions.Where(x => x.TransType == "A");

        //where SpecialData is B

        var transSpecialDataB = transA.Where(x => x.RelatedData.SpecialData == "B");

        //now you need to get your products
        var products = transSpecialDataB.Select(x => x.Product).ToList();

希望有帮助

【讨论】:

    【解决方案2】:

    在黑暗中拍摄,没有任何数据来测试它。

    data = data.Where(p=> p.Transactions
                                .Any(t => t.TransType == 'A' && 
                                     t => t.RelatedData.FirstOrDefault().SpecialData == 'B') 
                     );
    

    请注意,您不需要t =&gt; p.ProductID == t.ProductID,因为所有Transactions 都应该与Product 相关。

    我在这里使用FirstOrDefault(),因为它似乎可以返回超过 1 个结果。如果您要在包含多个元素的序列上使用 SingleSingleOrDefault,则会引发异常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多