我如何在 LINQ 中使用 Count with condition
How can i use Count with condition in LINQ
我想知道客户参加我们活动的次数。所以 sql 代码应该是这样的。
SELECT COUNT(CustomerID)
FROM EventsParticipants
WHERE (CustomerID == Session["CustomerID"]);
而LINQ代码是这样的我没记错,它会returnCount()的值对
var recordcount = db.EventParticipants.Where(Session["CustomerID] == db.EventParticipants.CustomerID).Count();
但是return这个错误码
'DbSet<EventParticipants>' does not contain a definition for 'CustomerID' and no accessible extension method 'CustomerID' accepting a first argument of type 'DbSet<EventParticipants>' could be found (are you missing a using directive or an assembly reference?) LeafLife
试试这个:
var id = Session["CustomerID"];
var recordcount = db.EventParticipants.Count(t=> id == t.CustomerID);
以后做Count
的时候,会在得到所有结果后在内存中统计。本质上它会做 SELECT * FROM EventsParticipants WHERE (CustomerID == Session["CustomerID"]);
然后在内存中它会找到有多少项目。 (不要这样做)
如果您执行上面显示的操作,将创建与您预期相同的查询,并且会更快。
您需要传递一个带有实体的 lambda 和 returns 一个 bool
,就像这样
var id = Session["CustomerID"];
var recordcount = db.EventParticipants.Where(x => x.CustomerID == id).Count();
请注意,您还需要将 id 放入单独的变量中,因为 EF 无法将 Session
转换为 SQL。
您需要先将 Session["CustomerID"]
值分配给一个变量,然后才能在 EF Linq 查询中使用它。
此外,您无需过滤然后获取计数,您可以直接在 LINQ 计数函数中提及条件。请参考以下
var id = Convert.ToInt32(Session["CustomerID"]); // Assuming this as int
var recordcount = db.EventParticipants.Count(x => x.CustomerID == id);
Lambda 表达式
每当您在 LINQ 中看到 Func<...>
或 Expressions<Func<...>>
格式的参数时,您需要提供具有正确输入参数和正确 return 值的函数。
Func<Ta, Tb, Tc>
表示具有两个输入参数和一个 return 值的任何方法。第一个参数是Ta类型,第二个参数是Tb类型。 return 值是 Tc 类型。以下方法都可以:
bool String.Equals(string x, string y);
Shop FindShop(Product product, decimal maximumPrice);
当然,这些类型必须与通用 LINQ 方法中的其他类型相匹配。
例如,如果您有 Customers
和 Orders
,并且您想要创建 PackingSlips
,您可能需要为此使用 Enumerable.Join。
public static IEnumerable<TResult> Join<TOuter,TInner,TKey,TResult> (
this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner,
Func<TOuter,TKey> outerKeySelector,
Func<TInner,TKey> innerKeySelector,
Func<TOuter,TInner,TResult> resultSelector);
TOuter的实际类型是Customer
,TInner
的实际类型是Order。要生成结果,您可以使用参数 resultSelector:
Func<TOuter,TInner,TResult> resultSelector
你的情况:
Func<Customer, Order , PackingSlip> resultSelector
这意味着,您必须提供一个具有两个输入参数的函数:Customer 和 Order,并且 return 是一个 PackingSlip:
PackingSlip CreatePackingSlip(Customer customer, Order order);
因此您将按如下方式使用 Join:
IEnumerable<Customer> customers = ...
IEnumerable<Order> orders = ...
IEnumerable<PackingSlip> packingSlips = customers.Join(orders,
... // parameter keySelector, see later,
// parameter resultSelector:
CreatePackingSlip);
这个也可以,但不是很方便,因此不会经常使用。例如,如果您有以下方法怎么办:
PackingSlip CreatePackingSlip(Order order, Customer customer);
为此创建了 lambda 表达式。它的格式为:
(...) => ...
这意味着:创建一个Func<...>
,或一个Action<,输入参数位于括号之间和箭头后面的代码中。例如
Func<Customer, Order, PackingSlip> resultSelector
(customer, order) => CreatePackingSlip(order, customer);
等同于:
PackingSlip CreatePackingSlip(Customer customer, Order order)
{
return CreatePackingSlip(order, customer); // call the other overload
}
但实际上您可以为此使用任何代码块:
(customer, order) => new PackingSlip()
{
Customer = customer,
Order = Order,
});
甚至一小段代码:
(customer, order) =>
{
string addressLines = this.CreateAddressLines(customer);
var orderLines = this.CreateOrderLines(order);
decimal totalPrice = this.CalculateTotalPrice(order);
PackingSlip packingSlip = new PackingSlip()
{
Address = addressLines,
OrderLines = orderLines,
TotalPrice = totalPrice,
};
return packingSlip;
});
任何内容都可以,只要括号 (..., ...)
中的部分以正确的顺序提及 Func<...>
的参数,以及 =>
之后的部分 returns 函数的 return 值。
我答应了上面Join的参数keySelector
。它们用于指定您要加入的内容。在这种情况下:我们要将主键 Customer.Id
与外键 Order.CustomerId
:
匹配
IEnumerable<Customer> customers = ...
IEnumerable<Order> orders = ...
IEnumerable<PackingSlip> packingSlips = customers.Join(orders,
customer => customer.Id, // from every customer take the primary key in Id
order => order.CustomerId, // from every order take the foreign key CustomerId
// parameter resultSelector take the Customer and its matching Order
// to make one new PackingSlip:
(customer, order) => new PackingSlip()
{
Address = this.CreateAddressLines(customer),
OrderLines = this.CreateOrderLines(order),
TotalPrice = this.CalculateTotalPrice(order),
});
When using LINQ it helps to use plural nouns to name collections of items, and to use singular nouns to name elements of the collections.
所以如果你加入 customers
和 orders
(集合!),你的 lambda 表达式应该使用
// Get Schools, each with their Students:
schools.GroupJoin(students
school => school.Id,
student => student.SchoolId,
(school, studentsOfThisSchool) => new {...})
schools.GroupJoin(students
x => x.Id,
y => y.SchoolId,
(z, a) => new {...})
您真的必须查看代码才能理解 a
中的内容。
回到你的问题
显然你有一个 table 和 EventParticipants
,其中每个 EventParticipant
都有一个 属性 CustomerId
。您只想获取那些具有特定值 CustomerId
.
的 EventParticipants
int requestedCustomerId = Session["CustomerId"];
var result = dbContext.EventParticipants.
.Where(eventParticipant => eventParticipant.CustomerId == requestedCustomerId);
因为我使用复数和单数名词,所以很容易阅读:“从 EventParticipants table 中的每个 eventParticipant,检查其 属性 CustomerId 的值是否等于 requestedCustomerId。如果是这样,保留eventParticipant,如果没有,就不要使用。
现在您要计算 Where
之后剩下的 CustomerIds
。假设每个EventParticipant恰好有一个CustomerId,那么可以统计EventParticipants:
var eventParticipantCount = dbContext.EventParticipants.
.Where(eventParticipant => eventParticipant.CustomerId == requestedCustomerId)
.Count();
但如果您真的想计算 CustomerId,则首先必须 select 它们。如果您希望有重复的 CustomerIds:
,这将很有用
var uniqueCustomerIdCount = dbContext.EventParticipants.
.Where(eventParticipant => eventParticipant.CustomerId == requestedCustomerId)
// from every remaining eventParticipant select its CustomerId
.Select(eventParticipant => eventParticipant.CustomerId)
// remove duplicate CustomerIds:
.Distinct()
// and count what is left:
.Count();
我想知道客户参加我们活动的次数。所以 sql 代码应该是这样的。
SELECT COUNT(CustomerID)
FROM EventsParticipants
WHERE (CustomerID == Session["CustomerID"]);
而LINQ代码是这样的我没记错,它会returnCount()的值对
var recordcount = db.EventParticipants.Where(Session["CustomerID] == db.EventParticipants.CustomerID).Count();
但是return这个错误码
'DbSet<EventParticipants>' does not contain a definition for 'CustomerID' and no accessible extension method 'CustomerID' accepting a first argument of type 'DbSet<EventParticipants>' could be found (are you missing a using directive or an assembly reference?) LeafLife
试试这个:
var id = Session["CustomerID"];
var recordcount = db.EventParticipants.Count(t=> id == t.CustomerID);
以后做Count
的时候,会在得到所有结果后在内存中统计。本质上它会做 SELECT * FROM EventsParticipants WHERE (CustomerID == Session["CustomerID"]);
然后在内存中它会找到有多少项目。 (不要这样做)
如果您执行上面显示的操作,将创建与您预期相同的查询,并且会更快。
您需要传递一个带有实体的 lambda 和 returns 一个 bool
,就像这样
var id = Session["CustomerID"];
var recordcount = db.EventParticipants.Where(x => x.CustomerID == id).Count();
请注意,您还需要将 id 放入单独的变量中,因为 EF 无法将 Session
转换为 SQL。
您需要先将 Session["CustomerID"]
值分配给一个变量,然后才能在 EF Linq 查询中使用它。
此外,您无需过滤然后获取计数,您可以直接在 LINQ 计数函数中提及条件。请参考以下
var id = Convert.ToInt32(Session["CustomerID"]); // Assuming this as int
var recordcount = db.EventParticipants.Count(x => x.CustomerID == id);
Lambda 表达式
每当您在 LINQ 中看到 Func<...>
或 Expressions<Func<...>>
格式的参数时,您需要提供具有正确输入参数和正确 return 值的函数。
Func<Ta, Tb, Tc>
表示具有两个输入参数和一个 return 值的任何方法。第一个参数是Ta类型,第二个参数是Tb类型。 return 值是 Tc 类型。以下方法都可以:
bool String.Equals(string x, string y);
Shop FindShop(Product product, decimal maximumPrice);
当然,这些类型必须与通用 LINQ 方法中的其他类型相匹配。
例如,如果您有 Customers
和 Orders
,并且您想要创建 PackingSlips
,您可能需要为此使用 Enumerable.Join。
public static IEnumerable<TResult> Join<TOuter,TInner,TKey,TResult> (
this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner,
Func<TOuter,TKey> outerKeySelector,
Func<TInner,TKey> innerKeySelector,
Func<TOuter,TInner,TResult> resultSelector);
TOuter的实际类型是Customer
,TInner
的实际类型是Order。要生成结果,您可以使用参数 resultSelector:
Func<TOuter,TInner,TResult> resultSelector
你的情况:
Func<Customer, Order , PackingSlip> resultSelector
这意味着,您必须提供一个具有两个输入参数的函数:Customer 和 Order,并且 return 是一个 PackingSlip:
PackingSlip CreatePackingSlip(Customer customer, Order order);
因此您将按如下方式使用 Join:
IEnumerable<Customer> customers = ...
IEnumerable<Order> orders = ...
IEnumerable<PackingSlip> packingSlips = customers.Join(orders,
... // parameter keySelector, see later,
// parameter resultSelector:
CreatePackingSlip);
这个也可以,但不是很方便,因此不会经常使用。例如,如果您有以下方法怎么办:
PackingSlip CreatePackingSlip(Order order, Customer customer);
为此创建了 lambda 表达式。它的格式为:
(...) => ...
这意味着:创建一个Func<...>
,或一个Action<,输入参数位于括号之间和箭头后面的代码中。例如
Func<Customer, Order, PackingSlip> resultSelector
(customer, order) => CreatePackingSlip(order, customer);
等同于:
PackingSlip CreatePackingSlip(Customer customer, Order order)
{
return CreatePackingSlip(order, customer); // call the other overload
}
但实际上您可以为此使用任何代码块:
(customer, order) => new PackingSlip()
{
Customer = customer,
Order = Order,
});
甚至一小段代码:
(customer, order) =>
{
string addressLines = this.CreateAddressLines(customer);
var orderLines = this.CreateOrderLines(order);
decimal totalPrice = this.CalculateTotalPrice(order);
PackingSlip packingSlip = new PackingSlip()
{
Address = addressLines,
OrderLines = orderLines,
TotalPrice = totalPrice,
};
return packingSlip;
});
任何内容都可以,只要括号 (..., ...)
中的部分以正确的顺序提及 Func<...>
的参数,以及 =>
之后的部分 returns 函数的 return 值。
我答应了上面Join的参数keySelector
。它们用于指定您要加入的内容。在这种情况下:我们要将主键 Customer.Id
与外键 Order.CustomerId
:
IEnumerable<Customer> customers = ...
IEnumerable<Order> orders = ...
IEnumerable<PackingSlip> packingSlips = customers.Join(orders,
customer => customer.Id, // from every customer take the primary key in Id
order => order.CustomerId, // from every order take the foreign key CustomerId
// parameter resultSelector take the Customer and its matching Order
// to make one new PackingSlip:
(customer, order) => new PackingSlip()
{
Address = this.CreateAddressLines(customer),
OrderLines = this.CreateOrderLines(order),
TotalPrice = this.CalculateTotalPrice(order),
});
When using LINQ it helps to use plural nouns to name collections of items, and to use singular nouns to name elements of the collections.
所以如果你加入 customers
和 orders
(集合!),你的 lambda 表达式应该使用
// Get Schools, each with their Students:
schools.GroupJoin(students
school => school.Id,
student => student.SchoolId,
(school, studentsOfThisSchool) => new {...})
schools.GroupJoin(students
x => x.Id,
y => y.SchoolId,
(z, a) => new {...})
您真的必须查看代码才能理解 a
中的内容。
回到你的问题
显然你有一个 table 和 EventParticipants
,其中每个 EventParticipant
都有一个 属性 CustomerId
。您只想获取那些具有特定值 CustomerId
.
int requestedCustomerId = Session["CustomerId"];
var result = dbContext.EventParticipants.
.Where(eventParticipant => eventParticipant.CustomerId == requestedCustomerId);
因为我使用复数和单数名词,所以很容易阅读:“从 EventParticipants table 中的每个 eventParticipant,检查其 属性 CustomerId 的值是否等于 requestedCustomerId。如果是这样,保留eventParticipant,如果没有,就不要使用。
现在您要计算 Where
之后剩下的 CustomerIds
。假设每个EventParticipant恰好有一个CustomerId,那么可以统计EventParticipants:
var eventParticipantCount = dbContext.EventParticipants.
.Where(eventParticipant => eventParticipant.CustomerId == requestedCustomerId)
.Count();
但如果您真的想计算 CustomerId,则首先必须 select 它们。如果您希望有重复的 CustomerIds:
,这将很有用var uniqueCustomerIdCount = dbContext.EventParticipants.
.Where(eventParticipant => eventParticipant.CustomerId == requestedCustomerId)
// from every remaining eventParticipant select its CustomerId
.Select(eventParticipant => eventParticipant.CustomerId)
// remove duplicate CustomerIds:
.Distinct()
// and count what is left:
.Count();