C# 用Linq选择top1
事实上,我正在与Linq和UOW(工作单元)合作,我正在与Linq一起轻松访问bbdd。我知道如果我想得到一个表的第一行,我可以这样做:C# 用Linq选择top1,c#,sql-server,asp.net-mvc,linq,unit-of-work,C#,Sql Server,Asp.net Mvc,Linq,Unit Of Work,事实上,我正在与Linq和UOW(工作单元)合作,我正在与Linq一起轻松访问bbdd。我知道如果我想得到一个表的第一行,我可以这样做: int test4 = (from p in uow.ProductR.context.product where p.Id == 1715 select p.Id).FirstOrDefault(); 将在SQL Server中执行此操作的: SELECT TOP (1) [Extent1]
int test4 = (from p
in uow.ProductR.context.product
where p.Id == 1715 select p.Id).FirstOrDefault();
将在SQL Server中执行此操作的:
SELECT TOP (1)
[Extent1].[Id] AS [Id]
FROM [dbo].[product] AS [Extent1]
WHERE 1715 = [Extent1].[Id]
我的问题是,我可以用LINQ对UOW的通用存储库进行同样的操作吗?我是说,当我执行
int test2 = uow.ProductR.Get(p => p.Id == 1715).Select(p => p.Id).FirstOrDefault();
或
在SQL Server中,我得到:
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name],
FROM [dbo].[product] AS [Extent1]
WHERE 1715 = [Extent1].[Id]
当然,使用第二种方法,当数据库有500k行时,速度会很慢。(我有更多的专栏,而不仅仅是2篇)
编辑:下面是带有GET声明的类
public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
{
internal contextEntities context;
internal DbSet<TEntity> dbSet;
public GenericRepository(contextEntities context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "")
{
IQueryable<TEntity> query = this.dbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
return orderBy(query).AsQueryable();
}
else
{
return query.AsQueryable();
}
}
}
公共类GenericRepository:IGenericRepository其中tenty:class
{
内部语境;
内部数据库集;
公共通用存储库(上下文上下文)
{
this.context=上下文;
this.dbSet=context.Set();
}
公共虚拟IEnumerable Get(
表达式筛选器=空,
Func orderBy=null,
字符串includeProperties=“”)
{
IQueryable query=this.dbSet;
if(过滤器!=null)
{
query=query.Where(过滤器);
}
foreach(includeProperty.Split中的var includeProperty(新字符[]{',},StringSplitOptions.RemoveEmptyEntries))
{
query=query.Include(includeProperty);
}
if(orderBy!=null)
{
return orderBy(query.AsQueryable();
}
其他的
{
返回query.AsQueryable();
}
}
}
我希望我已经解释清楚了。
Get
需要返回一个IQueryable
,而不是像现在这样返回一个IEnumerable
。然后,Get
的参数也变得无用,因为调用者只能执行Get()。其中(…)
。API表面变得更干净,因为您可以删除参数
但您正在失去对数据库查询方式的控制。我假设您正在做一个用于测试目的的存储库(如果不是,那么拥有一个存储库可能是一个错误的选择)。测试以这种方式执行的查询变得更加困难。
Get
需要返回一个IQueryable
,而不是像现在这样返回一个IEnumerable
。然后,Get
的参数也变得无用,因为调用者只能执行Get()。其中(…)
。API表面变得更干净,因为您可以删除参数
但您正在失去对数据库查询方式的控制。我假设您正在做一个用于测试目的的存储库(如果不是,那么拥有一个存储库可能是一个错误的选择)。测试以这种方式执行的查询变得更加困难。返回IQueryable将给您带来更大的灵活性,但它也暴露了随意修改存储库中定义的查询的可能性。如果您想为使用您的存储库返回前N行的用户提供一种标准机制,您可以添加一些额外的可选属性(注意,如果您还想允许通过存储库进行分页,而不需要创建单独的机制或公开基础IQueryable,Take与Skip是一种有用的机制) 您可以将Get方法签名更改为以下内容:
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "", int? maxResults = null)
请注意,不需要调用AsQueryable(),因为IOrderedQueryable和IQueryable都实现了IEnumerable。相反,调用ToList()以具体化结果集,使其得以执行。返回IQueryable将给您带来更大的灵活性,但它也暴露了随意修改存储库中定义的查询的可能性。如果您想为使用您的存储库返回前N行的用户提供一种标准机制,您可以添加一些额外的可选属性(注意,如果您还想允许通过存储库进行分页,而不需要创建单独的机制或公开基础IQueryable,Take与Skip是一种有用的机制) 您可以将Get方法签名更改为以下内容:
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "", int? maxResults = null)
请注意,不需要调用AsQueryable(),因为IOrderedQueryable和IQueryable都实现了IEnumerable。相反,调用ToList()以具体化结果集,使其执行。如何实现方法
Get
?此语句uow.ProductR.Get(p=>p.Id==1715)
应使用选择TOP 1
方法如何实现?此语句uow.ProductR.Get(p=>p.Id==1715)代码>应该使用选择前1名
,这就是问题所在。我没见过那该死的数字。上面的代码是测试代码,但目前我有几个正确实现UOW模式的项目,这些项目运行良好,有50到400人同时在线。(有5层的项目,前面、后面、应用程序、dal…)我不明白你为什么说这可能不是一个正确的选择。我需要阅读并告诉我一些事情?谢谢,如果有更多的信息,我可以回答得更好。为什么要添加存储库(而不是直接使用EF)?我有一个由UOW管理的EF。因此,当我需要来自前端的数据时,我访问Dal,在那里我在UOW上进行LINQ查询。这就是我现在介绍的简化流程示例。为什么要使用存储库?EF已经是一个存储库并且实现了UOW。我想当我开始使用它的时候,我对它们的了解还不够。可能会在新项目和EF6 MVC5中使用,这就是问题所在。我没见过那该死的数字。上面的代码是测试代码,但目前我有几个正确实现UOW模式的项目,这些项目运行良好,有50到400人同时在线。(项目有5层,前面,后面,应用程序,dal…)我不明白你为什么说
if (orderBy != null)
{
return maxResults.HasValue() ? orderBy(query).Take((int)maxResults).ToList() : orderBy(query).ToList();
}
else
{
return maxResults.HasValue() ? query.take((int)maxResults).ToList() : query.ToList();
}