C# LINQ-带和IF的分组方式
我试着用linq写一些对我来说很容易用SQL写的东西。你知道怎么做吗 选择Items.IdItem, 项目名称, 以数量计1, SUMIFState.IdStatus=1,1,0(可用) 从项目 内连接状态 关于Items.IdItem=State.IdItem 按项分组。IdItem 我写了这样的东西: var result=来自_context.items中的项 items.IdItem上的_context.state中的联接状态等于state.IdItem 按{items.IdItem,items.Name}将项目分组到g中 选择新{Name=g.Key.Name,IdItem=g.Key,IdItem,Quantity=g.Count,Availible=??}C# LINQ-带和IF的分组方式,c#,entity-framework,linq,C#,Entity Framework,Linq,我试着用linq写一些对我来说很容易用SQL写的东西。你知道怎么做吗 选择Items.IdItem, 项目名称, 以数量计1, SUMIFState.IdStatus=1,1,0(可用) 从项目 内连接状态 关于Items.IdItem=State.IdItem 按项分组。IdItem 我写了这样的东西: var result=来自_context.items中的项 items.IdItem上的_context.state中的联接状态等于state.IdItem 按{items.IdItem,i
有什么提示吗?如果您在数据库中设置了关系,并在模型中设置了导航属性(由生成器完成),那么在Linq中,对于没有直接关系的表,您很少需要联接 第二,你在这里不是真的追求总和,是吗。查看求和函数和字段名,看起来更像是在检查是否可用
var result = from i in _context.Items
group i by i.IdItem into g
select new {
IdItem = g.Key,
Name = g.First().Name,
Quantity = g.Count(),
Available = g.Any(it => it.State.IdStatus == 1)
};
编辑:如果你的总数是故意的,那么你可以用它来替换可用部分,对吗
Available = g.Sum(it => it.State.IdStatus)
编辑:此选项基于您的数据/模型和顶部的SQL:
var result = from i in _context.Items
select new
{
i.IdItem,
i.Name,
Quantity = i.States.Count(),
Available = i.States.Count(x => x.IdStatus == 1)
};
示例代码和结果:
string defaultConString = @"server=.\SQLExpress;Database=SampleDb;Trusted_Connection=yes;";
void Main()
{
var _context = new MyContext(defaultConString);
var result = from i in _context.Items
select new
{
i.IdItem,
i.Name,
Quantity = i.States.Count(),
Available = i.States.Count(x => x.IdStatus == 1)
};
result.Dump(); // linqPad
}
public class MyContext : DbContext
{
public MyContext(string connectionString)
: base(connectionString)
{ }
public DbSet<Item> Items { get; set; }
public DbSet<State> States { get; set; }
}
[Table("Items")]
public partial class Item
{
public Item()
{
this.States = new List<State>();
OnCreated();
}
[Key]
public virtual int IdItem { get; set; }
public virtual string Name { get; set; }
public virtual System.DateTime ImportDate { get; set; }
public virtual System.DateTime ReturnDate { get; set; }
public virtual IList<State> States { get; set; }
partial void OnCreated();
}
[Table("States")]
public partial class State
{
public State()
{
OnCreated();
}
[Key]
public virtual int IdState { get; set; }
public virtual string SmId { get; set; }
public virtual string Number { get; set; }
public virtual int IdItem { get; set; }
public virtual int IdStatus { get; set; }
public virtual Item Item { get; set; }
partial void OnCreated();
}
g、 Sumi=>i.IdStatus==1?1:0?在Quantity属性中对组进行计数。你们可以用类似的方法计算g的条件和。编辑:与塞尔文的建议差不多-@塞尔文:我建议你们发布一个回复,这是我的第一个想法,但我只能使用组中的字段……你们说得对。我不需要加入,谢谢。我尝试了你的解决方案,问题是项目和状态之间的关系是一对多的,所以我不能这样访问它:Available=g.Sumit=>it.State.IdStatus有什么提示吗?@yarnsik,哪一个是多方面的?请给出一些示例数据以供理解。以下是类和示例数据:正如您所看到的,我在查询中使用了SUM和IF,因为IdStatus可以有不同的值,而不仅仅是0或1。“我真的很感谢你的帮助。”yarnsik看到数据和模型帮助很大。根本不需要分组。我现在正在编辑它,以符合您的要求,即您提供的SQL-在更正后。我测试了您的解决方案并正确计算了数据,但它返回的行数与表状态中的行数相同。所以对于样本数据,结果是6行,而不是3行。第二个问题是生成的SQL很糟糕:选择baz.IdItem、baz.Name,从baz.IdItem=u.IdItem的状态u中选择Count*,从x状态x中选择Count*,其中x.IdStatus=1和baz.IdItem=x.IdItem可从项目baz中获得
IdItem Name Quantity Available
1 Test01 3 2
2 Test02 2 1
3 Test03 1 0