如何编写扩展方法转换IQueryable<T>和IEnumerable<T>到ReadOnlyCollection<T>?
谢谢
我试图从一个IEnumerable集合中选择一个列,该列在运行时只有我知道的类型.我能想到使用它的唯一方法是使用LINQ表达式来构建动态调用Queryable.Select.但是,我在确定实现此目的的正确语法时遇到了很多麻烦.
我是如何在编译时知道我需要的所有事情的幸福世界中做到这一点的一个例子,我的代码看起来像这样:
' Create an IEnumerable(Of String)
Dim strings = { "one", "two", "three" }
' Produce a collection with elements {3,3,5}
Dim stringLengths = strings.Select(Function(x) x.Length)
Run Code Online (Sandbox Code Playgroud)
不幸的是,实际上我不知道我拥有的集合是类型String,还是我想要选择的属性Length.我所拥有的是IEnumerable一系列项目,以及PropertyInfo我想要选择的列,它为我提供了所需的所有类型信息.
就表达式而言,我已经能够创建一个LINQ表达式,我相信它将代表我通常会传递给选择的lambda(假设我尝试使用String和String.Length执行上面的相同操作)
' pi is the PropertyInfo containing the Length property I am trying to select.
' pi.DeclaringType is String and pi.Name is Length
Dim targetItem = Expression.Parameter(pi.DeclaringType, "x")
Dim targetProperty = Expression.Property(targetItem, pi.Name)
' Produces the lambda<Function(x) x.Length>
Dim selectLambda …Run Code Online (Sandbox Code Playgroud) 我已经添加了必需的列和正确的DataPropertyName,我使用以下代码来填充datagridview.但是,我的dataGridView仅显示列标题和一个空行.我的代码出了什么问题?
public static IQueryable<Kolon> kolonlistele()
{
using (Pehlivan.pehkEntities ctx = new Pehlivan.pehkEntities())
{
var result = from k in ctx.Kolons
select k;
return result;
}
}
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.DataSource = veritabani_islemleri.kolonlistele();
}
Run Code Online (Sandbox Code Playgroud) 我已经看过许多关于制作SPA(单页面应用程序)的教程,其中许多都使用了外部库,如breezejs和jaydatajs,以获得自动数据服务层.
这些库期望我将公开他们可以查询的IQueryable对象.
我的问题是,从服务器中暴露出IQueryable的风险是什么?我想知道如果用这些js库制作这个快捷方式值得,或者我应该在服务器中公开我自己的函数并在客户端自己实现dataservice.
问题是,当暴露Iqueryable时,我可以使用breezejs来创建用于使用linq like语法进行过滤和分页的查询.如果我不使用它,我将不得不在服务器中实现这些过滤和分页功能.并在javascript中实现对它们的调用.
我希望我很清楚:-)
我是ASP.NET MVC新手(但.NET经验丰富的开发者),我正在努力学习如何正确设置Web应用程序基础结构.存储库模式是我现在正在考虑的,在过去几天阅读了几十篇博客/文章/答案后,我仍然不确定如何以正确的方式使用它.我正在学习Pro ASP.NET MVC 4 Adam Freeman,这里是基于本书的存储库接口代码:
public interface IRepository<T>
{
IQueryable<T> FindAll();
IQueryable<T> Find(Expression<Func<T, bool>> predicate);
void Add(T newEntity);
void Remove(T entity);
T FindById(long id);
}
Run Code Online (Sandbox Code Playgroud)
经过更多的在线研究,我意识到许多人认为从存储库中返回IQueryable是不好的做法,我(大多数时候)可以理解为什么.但是,我似乎无法找到具体替代方案的答案?我知道有一个自定义存储库的想法,对于每个实体,每个可能的查询都有专门的方法,基本上会返回IEnumerable而不是IQueryable ......但这对我来说似乎不对(它也不是优雅的解决方案)许多代码编写和可能的代码冗余等...).
还有什么其他选择?
下面的代码在排序方面有什么问题?排序代码被命中,但排序从未应用于结果。
var results = new List<Location>();
var county = context.boc_County.Where(x => x.Description.Contains(phrase.ToLower())).ToList();
results.AddRange(_mapper.MapCountyFromDb(county));
var town = context.boc_Town.Where(x => x.Description.Contains(phrase.ToLower())).ToList();
results.AddRange(_mapper.MapTownFromDb(town));
if (orderBy == "Identifier")
{
if (direction == "ASC")
results = results.OrderBy(x => x.Identifier);
else
results = results.OrderByDescending(x => x.Identifier);
}
if (orderBy == "Type")
{
if (direction == "ASC")
results = results.OrderBy(x => x.LocationType.ToString());
else
results = results.OrderByDescending(x => x.LocationType.ToString());
}
if (orderBy == "Description")
{
if (direction == "ASC")
results = results.OrderBy(x => x.Description);
else
results = results.OrderByDescending(x …Run Code Online (Sandbox Code Playgroud) 我试图使用IQueryable Include方法加载导航属性,但是虽然表达式是正确的我没有得到任何结果
这是代码
protected void LoadNavigationProperty(ref IQueryable<T> query, Expression<Func<T, object>>[] navigationProperties)
{
if ((query != null) && (navigationProperties != null))
{
foreach (Expression<Func<T, object>> navigationProperty in navigationProperties)
{
query.Include<T, object>(navigationProperty);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我在查询上设置了一个断点.包括并检查数据:
navigationProperties[0] = { n => n.UserStatus }
navigationProperties[1] = { n => n.PrivilegeLevel }
Run Code Online (Sandbox Code Playgroud)
在单步执行包含行之后,我再次检查了查询值,发现它不包含导航属性
我有两个查询,两个查询都产生相同的结果,但我想知道哪一个更有效。下面是查询,我只写了查询子句。两个查询的内部条件相同。
最后,我尝试了下面的代码,它显示“IQueryable().ToList().Where();” 更好。有几个问题我不明白: 1. 没有看到我下面的临时代码,哪个查询更有效?2.据我所知,IQueryable非常适合查询远程数据。那么,是否应该先过滤掉项目,然后使用 ToList,这样我们就不需要对不相关的项目执行 ToList 函数?(如果是这种情况,那么为什么下面的代码说查询 2 更有效?)
Stopwatch st1 = new Stopwatch();
Stopwatch st2 = new Stopwatch();
int counter = 10000;
IEnumerable<Employee> iEmp = null;
IQueryable<Employee> qEmp = null;
BindingList<Employee> bList = new BindingList<Employee>();
for (int i = 1; i <= counter; ++i)
{
bList.Add(new Employee
{
Department = $"Dept - {i}",
EmployeeID = i,
EmployeeName = $"Employee - {i}",
Salary = i + 10000
});
}
iEmp = bList.AsEnumerable<Employee>();
qEmp = bList.AsQueryable<Employee>();
st1.Start();
var …Run Code Online (Sandbox Code Playgroud) 我有这个想法来创建一个执行不同类型操作的 IQueryables 的“列表”。
所以基本上:
var query1 = Enumerable.Empty<Person>().AsQueryable().Where(e => e.Name == "Ronald");
var query2 = Enumerable.Empty<Person>().AsQueryable().Where(e => e.Age == 43);
var query3 = Enumerable.Empty<Person>().AsQueryable().Select(e => e.EyeColor);
var listOfQueries = new List<IQueryable<Person>
{
query1,
query2,
query3
};
Run Code Online (Sandbox Code Playgroud)
现在,我也有这个充满“Persons”的 DbSet,我想“应用”针对该 DbSet 的所有查询。我该怎么做呢?有可能吗?
更新的示例:
var personQueryFactory = new PersonQueryFactory();
var personQueryByFirstname = personQueryFactory.CreateQueryByFirstname("Ronald"); //Query by Firstname.
var personQueryByAge = personQueryFactory.CreateQueryByAge(42); //Query by age.
var personQueryByHasChildWithAgeOver = personQueryFactory.CreateQueryByChildAgeOver(25); //Query using a "join" to the child-relationship.
var personQuerySkip = personQueryFactory.Take(5); //Only get the 5 first …Run Code Online (Sandbox Code Playgroud) iqueryable ×10
c# ×6
linq ×4
.net ×1
breeze ×1
ienumerable ×1
javascript ×1
linq-to-sql ×1
odata ×1
performance ×1
reflection ×1
sorting ×1
vb.net ×1
wcf ×1
winforms ×1