linq:在不同类型的条件下加入linq

时间:2017-11-17 05:46:29

标签: c# mysql sql-server entity-framework

我有两张表,例如promotionalOffers和PromotionalOffersUsed
我现在使用连接获取匹配记录我想要包含不同的条件,例如 PromotionalOffers.ISVCSPId = 10和PromotionalOffersUsed.OfferId为空

我使用左连接工作预期在sql中编写了查询,但我无法在linq中编写相同的查询

这里是我的SQL查询

SELECT * 
FROM PromotionalOffers
left JOIN PromotionalOffersUsed ON PromotionalOffers.Id = PromotionalOffersUsed.OfferId where PromotionalOffers.ISVCSPId =10 and PromotionalOffersUsed.OfferId is null

我的linq查询

(from s in db.PromotionalOffers
 join e in db.PromotionalOffersUsed on s.Id equals e.OfferId
 where s.ISVCSPId == iSVCSPData.Id
 select s).ToListAsync();

我无法在此处加入左连接

3 个答案:

答案 0 :(得分:1)

对于左连接,您必须这样做,以下是linq

中左外连接的示例
var leftFinal =
        from l in lefts
        join r in rights on l equals r.Left into lrs
        from lr in lrs.DefaultIfEmpty()
        select new { LeftId = l.Id, RightId = ((l.Key==r.Key) ? r.Id : 0 };

查询

SELECT * 
FROM PromotionalOffers
left JOIN PromotionalOffersUsed ON PromotionalOffers.Id = PromotionalOffersUsed.OfferId where PromotionalOffers.ISVCSPId =10 and PromotionalOffersUsed.OfferId is null

linq中的暂定查询

var leftFinal =
        (from l in PromotionalOffers.Where(p=> p.ISVCSPId ==10) 
        join r in PromotionalOffersUsed on l.ID equals r.OfferId  into lrs
        from lr in lrs.DefaultIfEmpty()
        select 
          new { LeftId = l.Id, RightId = ((l.ID==r.OfferId  ) ? r.OfferId   : -1 }
        ).where(d=> d.RightID != -1);

答案 1 :(得分:1)

试试这个;

(from s in db.PromotionalOffers
 join e in db.PromotionalOffersUsed on s.Id equals e.OfferId into joinT
 from e in joinT.DefaultIfEmpty()
 where s.ISVCSPId == 10 && (e == null || e.OfferId == null)
 select new { PromotionalOffers = s, PromotionalOffersUsed = joinT } ).ToListAsync();

答案 2 :(得分:0)

显然,PromotionalOffers之间存在一对多关系 和PromotionalOffersUsed:每个PromotionalOffer都有零个或多个PromotionalOffersUsed,而每个PromotionalOffersUsed只属于一个PromotionalOffer

如果您遵循entity framework conventions to design this one-to-many关系,则不需要进行连接,也不需要左外连接,而是使用ICollection类:

class PromotionalOffer
{
    public int Id {set; set;}
    // a PromotionalOffer has zero or more PromotionalOfferUsed
    public virtual ICollection<PromotionalOfferUsed> PromitionalOffersUsed {get; set;}
    ...
}
class PromotionalOfferUsed
{
    public int Id {set; set;}
    // every PromotionalOffersUsed belongs to exactly one PromotionalOffer
    // using foreign key:
    public int PromotionalOfferId {get; set;}
    public PromotionalOffer PromotionalOffer {get; set;}
    ...
}
class MyDbContext: DbContext
{
    public DbSet<PromotionalOffer> PromotionalOffers {get; set;}
    public DbSet<PromotionalOfferUsed> PromotionalOffersUsed {get; set;
}

通常,这对于实体框架来说已经足够了解您设计了一对多关系。

我们需要一些流畅的API的唯一原因是因为奇怪的复数:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // PromotionalOffersUsed are stored in a table with name PromotionOffersUsed:
    modelBuilder.Entity<PromotionalOfferUsed>().ToTable("PromotionalOffersUdsed");

    // Every PromotionalOffer has zero or more PromotionalOfferUsed
    // every PromotionalOfferUsed belongs to exactly one (required) PromotionalOffer
    // using foreign key PromtionalOfferId
    modelBuilder.Entity<PromotionalOffer>
        .HasMany(promotionalOffer => promotionalOffer.PromotionalOffersUsed)
        .WithRequired(promotionalOfferUsed => promotionOfferUsed.PromotionalOffer)
         .HasForeignKey(post => post.BlogId);

    base.OnModelCreating(modelBuilder);
}

再一次,如果您有标准单数和复数(人/人;帐户/帐户,订单/订单),则不需要这种流畅的API。

现在您的查询:在集合中思考,而不是在联接中。

  

将所有ISVCSPId等于10的PromotionalOffers一起给我   使用OfferId等于null的所有PromotionalOffersUsed

using (var dbContext = new MyDbContext())
{
    var result = dbContext.PromotionalOffers
        .Where(promotionalOffer => promotionalOffer.ISVCSPID == 10)
        .Select(promotionalOffer => new
        {   // select only the properties you will be using:
            ISVCSPID = promotionalOffers.ISVSPID,
            ... // other properties from promotionalOffers

            PromotionalOffersUsed = promotionalOffers.PromtionalOffersUsed
                .Where(promotionalOffersUsed => promotionalOffersUsed.OfferId == null)
                .Select(promotionalOffersUsed => new
                {
                     // again: select only the properties of PromotionalOffersUsed
                     // that you will be using
                     Id = promotionalOffersUsed.Id,
                     ... // other properties
                })
                .ToList();
        }
}

因为实体框架知道有一对多的外键,所以它会为你做正确的左外连接。