如何根据子表和子表相关数据表中的值查询父表?

时间:2018-02-23 16:12:50

标签: c# sql sql-server database linq

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

Tables

产品有很多交易。 “A”类型的事务具有带SpecialData的RelatedData条目。

我想获取所有产品记录,这些记录的最后交易类型为'A',特殊数据值为'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
                    );

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

2 个答案:

答案 0 :(得分:1)

您的目标是:

  

我想获得最后的所有产品记录   具有SpecialData值'B'的类型'A'的事务

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

假设您的实体是这样的:

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();

希望这个帮助

答案 1 :(得分:0)

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

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

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

我在这里使用FirstOrDefault(),因为它似乎可以返回超过1个结果。如果您对具有多个元素的序列使用SingleSingleOrDefault,则会抛出异常。