我想将这两个linq查询合并为一个查询 有可能吗?
var chestProducts = (from w in WareHouse
join c in Chests on w.Id equals c.WareHouseId
join p in Products on c.Id equals p.ContainerId
where (p.IsContainerChest == true && w.Id == 1)
select p
).ToList();
var boxProducts = (from w in WareHouse
join b in Boxes on w.Id equals b.WareHouseId
join p in Products on b.Id equals p.ContainerId
where (p.IsContainerChest != true && w.Id == 1)
select p
).ToList();
var allProducts = chestProducts.AddRange(boxProducts);
我应该使用两个查询吗?
这种关系是健康的吗?
编辑:简化了Boxs和Chests表,它们具有不同的字段
答案 0 :(得分:3)
尝试一下:
var allProducts = chestProducts.Concat(boxProducts);
或者您也可以使用联盟
var allProducts = Enumerable.Union(chestProducts, boxProducts);
答案 1 :(得分:2)
好的,从您的评论中,我可以看到您首先在代码中使用EF6。在那种情况下,我将使用Table per Hierarchy并将Box
和Chest
放在一个表中(它们仍将是单独的类)。一个(重要的)警告:我已经与EF Core专门合作了一段时间,而我还没有对此进行测试。但是我反复使用了这种模式,效果很好。
您的实体应如下所示:
public class WareHouse
{
[Key]
public int Id { get;set; }
public string Name {get;set;}
public ICollection<Container> Containers {get;set;}
}
public abstract class Container
{
[Key]
public int Id {set;set;}
public int WareHouseId {get;set;}
[ForeignKey(nameof(WareHouseId))]
public WareHouse WareHouse {get;set;}
public string Name {get;set;}
public ICollection<Product> Products {get;set;}
}
public class Box : Container
{
// box specific stuff here
}
public class Chest : Container
{
// chest specific stuff here
}
public class Product
{
[Key]
public int Id {set;set;}
public int ContainerId {get;set;}
[ForeignKey(nameof(ContainerId))]
public Container Container {get;set;}
}
您的上下文如下:
public class MyContext : DbContext
{
public virtual DbSet<WareHouse> WareHouses {get;set;}
public virtual DbSet<Container> Containers {get;set;}
public virtual DbSet<Product> Products {get;set;}
protected override void OnModelCreating(ModelBuilder builder)
{
// puts the class name in a column, makes it human readable
builder.Entity<Container>().Hasdiscriminator<string>("Type");
// i don't think you need to do this, but if it doesn't work try this
// builder.Entity<Box>().HasBaseType(typeof(Container));
// builder.Entity<Chest>().HasBaseType(typeof(Container));
}
}
然后您可以像这样从id = 1的仓库中获取所有产品:
int warehouseId = 1;
Product[] allProducts = myContext.WareHouses
.Where(wh => wh.Id == warehouseId)
.SelectMany(wh => wh.Container)
//.OfType<Box>() if you only want products in boxes
.SelectMany(wh => wh.Products)
.ToArray();
我知道您在评论中说过,您倾向于使用linq的lambda语法,但是我觉得我应该指出,您在查询语法示例中进行了许多不必要的联接。如果您正确设置了一切,linq to实体将为您完成所有工作。