Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 修改EF结果并序列化到客户端_C#_Asp.net_Entity Framework - Fatal编程技术网

C# 修改EF结果并序列化到客户端

C# 修改EF结果并序列化到客户端,c#,asp.net,entity-framework,C#,Asp.net,Entity Framework,我正在从数据库中获取密钥列表,并根据特定条件对其进行修改。该列表被序列化为对AJAX调用的响应 但是,当我在此过程中多次修改列表时,Resharper告诉我“ienumerable的可能多重枚举” 我是否应该在涉及列表的所有行上使用ToList() 请推荐一种合适的方法: IEnumerable<decimal> foo = databaseContext.Foo.Select(f=>f.Key); if(something) foo = foo.Where(f=&g

我正在从数据库中获取密钥列表,并根据特定条件对其进行修改。该列表被序列化为对AJAX调用的响应

但是,当我在此过程中多次修改列表时,Resharper告诉我“
ienumerable的可能多重枚举”

我是否应该在涉及列表的所有行上使用
ToList()

请推荐一种合适的方法:

IEnumerable<decimal> foo = databaseContext.Foo.Select(f=>f.Key);

if(something)
    foo = foo.Where(f=>f.Bar > 5);

if(somethingElse)
    foo = foo.Where(f=>f.Bar > 15);

var json = new JavaScriptSerializer.Serialize(new { fooKeys = foo.ToList() });

HttpContext.Current.Response.Write(json);
IEnumerable foo=databaseContext.foo.Select(f=>f.Key);
如果(某物)
foo=foo.Where(f=>f.Bar>5);
如果(某物)
foo=foo.Where(f=>f.Bar>15);
var json=newJavaScriptSerializer.Serialize(new{fooKeys=foo.ToList()});
HttpContext.Current.Response.Write(json);

我认为您的代码不正确,当您在对象集上进行选择时,您会得到一个查询表。我认为您无法将查询表分配给IEnumerable

在使用IQueryable ToList()方法之前,queryAble实际上不会对db执行请求

因此,首先应该定义查询,然后使用ToList()方法对db执行查询,该方法将返回您的类型列表

你应该把你的代码重新排列成这样

var resultSetInMemory = new List<decimal>();

if(somethink) {
 resultSetInMemory = databaseContext.Foo
                                    .Where(f=>f.Bar > 5)
                                    .Select(f.key)
                                    .ToList();
}

if(somethingElse) {
 resultSetInMemory = databaseContext.Foo
                                   .Where(f=>f.Bar > 15)
                                   .Select(f.key)
                                   .ToList();
}

var json = new JavaScriptSerializer.Serialize(new { fooKeys = resultSetInMemory });
var resultSetInMemory=new List();
如果(想){
resultsteinmemory=databaseContext.Foo
.其中(f=>f.Bar>5)
.选择(f键)
.ToList();
}
如果(某物){
resultsteinmemory=databaseContext.Foo
.其中(f=>f.Bar>15)
.选择(f键)
.ToList();
}
var json=new JavaScriptSerializer.Serialize(新的{fooKeys=resultsteinmemory});

这是我经常看到的方法。希望这对你也有帮助。

Resharper的分析是正确的。您可能会多次执行查询。问题出在您的第一行:

IEnumerable<decimal> foo = databaseContext.Foo.Select(f=>f.Key);
另外,我猜这是您的疏忽,但是
foo
decimal
的可枚举项,但是您过滤了
Bar
属性。这甚至不会编译

编辑:我已冒昧地修改了您的原始代码(第一部分),以向您显示明细:

// databaseContext.Foo is a (presumably) DbSet<Foo> that implements 
// IQueryable<Foo>. Because the variable foo is set to be an IEnumerable<Foo> 
// and that IQueryable<Foo> implements IEnumerable<Foo> by calling 
// as AsEnumerable(), any further manipulation of the IEnumerable<Foo>
// will be with LINQ to Object and not Linq to SQL (with Entity Framework)
IEnumerable<Foo> foo = databaseContext.Foo;

// Because of the previous point, this will potentially execute the query
if(something)
    foo = foo.Where(f=>f.Bar > 5);

// And this will as well
if(somethingElse)
    foo = foo.Where(f=>f.Bar > 15);

// And ToList() will definitely execute it.
var json = new JavaScriptSerializer.Serialize(new { fooKeys = foo.Select(f => f.Key).ToList() });

HttpContext.Current.Response.Write(json);
//databaseContext.Foo是(大概)一个实现
//易读的。因为变量foo被设置为IEnumerable
//IQueryable通过调用
//作为AsEnumerable(),对IEnumerable的任何进一步操作
//将使用LINQ到对象,而不是LINQ到SQL(使用实体框架)
IEnumerable foo=databaseContext.foo;
//由于前面的一点,这可能会执行查询
如果(某物)
foo=foo.Where(f=>f.Bar>5);
//这也会
如果(某物)
foo=foo.Where(f=>f.Bar>15);
//ToList()肯定会执行它。
var json=newJavaScriptSerializer.Serialize(new{fooKeys=foo.Select(f=>f.Key.ToList());
HttpContext.Current.Response.Write(json);
现在,如果您改为这样做:

// DbSet<Foo> will create an IQueryable<Foo>. An Entity Framework IQueryProvider
// will compile this to an SQL when we want to materialize the query
IQueryable<Foo> foo = databaseContext.Foo;

// Now, if this is hit, it's fine because IQueryable.Where returns an IQueryable
// of the same type. We still live in the 
if(something)
    foo = foo.Where(f=>f.Bar > 5);

// Same point as before. foo is still an IQueryable<Foo> and the materialization
// is not provoked yet.
if(somethingElse)
    foo = foo.Where(f=>f.Bar > 15);

// Here, foo.Select() will return an IQueryable<decimal> (or whatever the type
// of the Foo.Key property is) and then ToList() will get the IEnumerable<decimal>
// version. At that point, any further manipulation is done through Linq to Object
// but the query won't be sent to the database until it is iterated (ie
// the IEnumerable<decimal>.GetEnumerator() is called). The IEnumerable<decimal>
// version of the will be passed to the List<T>(IEnumerable<T>) constructor
// which will iterate through the Enumerable with the GetEnumerator method.
var json = new JavaScriptSerializer.Serialize(new { fooKeys = foo.Select(f => f.Key).ToList() });

HttpContext.Current.Response.Write(json);
//DbSet将创建IQueryable。实体框架提供程序
//当我们想要具体化查询时,会将其编译为SQL
IQueryable foo=databaseContext.foo;
//现在,如果这个被命中,这是好的,因为IQueryable。哪里返回IQueryable
//同类的。我们仍然住在城市里
如果(某物)
foo=foo.Where(f=>f.Bar>5);
//和以前一样。foo仍然是一个IQueryable和物化
//还没有被激怒。
如果(某物)
foo=foo.Where(f=>f.Bar>15);
//这里,foo.Select()将返回IQueryable(或任何类型)
//Key属性的值为),然后ToList()将获得IEnumerable
//版本。在这一点上,任何进一步的操作都是通过Linq来完成的
//但是查询在被迭代之前不会被发送到数据库(即
//调用IEnumerable.GetEnumerator()。数不清的
//的版本将传递给列表(IEnumerable)构造函数
//它将使用GetEnumerator方法遍历可枚举项。
var json=newJavaScriptSerializer.Serialize(new{fooKeys=foo.Select(f=>f.Key.ToList());
HttpContext.Current.Response.Write(json);

如您所见,通过在开始和结束时使用
IQueryable
,直到
ToList()
,您仍将生活在
IQueryable
延迟查询执行世界中,Resharper将停止抱怨。

因此,您建议对数据库执行两个查询,同时丢失第一个查询的结果,甚至得不到与他应该得到的相同的结果?啊,不,这不太好。你是对的。更好的方法是在函数末尾说ToList(),通常在这里返回结果。谢谢您的输入。从一开始就将其作为一个通用列表,并在每种情况下使用
Where().Tolist()
是否是一个坏主意?是的。ToList()将执行一个查询。第一个将从数据库执行,其余的都将创建中间列表。当你对数据库的查询很好的时候,你应该考虑保持你的可查询性,所以你建议我做一个<代码>可查询的< /COD>,而不是上面的代码> iQueabd。这难道不会引起与resharper现在警告我的问题相同的问题吗?@Johan IQueryable在任何时候都不会列举。一份不可胜数的遗嘱。对不起,我没听懂。如果像我的示例中那样使用
IEnumerable
,问题仍然存在。你能举例说明你建议的方法吗?
// DbSet<Foo> will create an IQueryable<Foo>. An Entity Framework IQueryProvider
// will compile this to an SQL when we want to materialize the query
IQueryable<Foo> foo = databaseContext.Foo;

// Now, if this is hit, it's fine because IQueryable.Where returns an IQueryable
// of the same type. We still live in the 
if(something)
    foo = foo.Where(f=>f.Bar > 5);

// Same point as before. foo is still an IQueryable<Foo> and the materialization
// is not provoked yet.
if(somethingElse)
    foo = foo.Where(f=>f.Bar > 15);

// Here, foo.Select() will return an IQueryable<decimal> (or whatever the type
// of the Foo.Key property is) and then ToList() will get the IEnumerable<decimal>
// version. At that point, any further manipulation is done through Linq to Object
// but the query won't be sent to the database until it is iterated (ie
// the IEnumerable<decimal>.GetEnumerator() is called). The IEnumerable<decimal>
// version of the will be passed to the List<T>(IEnumerable<T>) constructor
// which will iterate through the Enumerable with the GetEnumerator method.
var json = new JavaScriptSerializer.Serialize(new { fooKeys = foo.Select(f => f.Key).ToList() });

HttpContext.Current.Response.Write(json);