通过 Entity Framework 请求数据时出错
error occurred when requesting data via Entity Framework
我正在构建一个 N 层应用程序,它必须发送 JSON 数据,这些数据是通过 Enity Framework 从 SQL Server 2012 读取的。
当我尝试请求一组用户时,我得到一个 "An error has occurred" 页面。它适用于硬编码数据。
这是我的代码:
public IEnumerable<User> Get()
{
IUserManager userManager = new UserManager();
return userManager.GetUsers();
}
public IEnumerable<User> GetUsers()
{
return repo.ReadUsers();
}
public IEnumerable<User> ReadUsers()
{
IEnumerable<User> users = ctx.Users.ToList();
return users;
}
"ctx" 是对 DbContext 对象的引用。
编辑:有效:
public IEnumerable<User> Get()
{
IList<User> users = new List<User>();
users.Add(new User() { FirstName = "TestPerson1" });
users.Add(new User() { FirstName = "TestPerson2" });
return users;
}
浏览器截图:http://i.imgur.com/zqG0qe0.png
编辑:完整错误(截图):http://i.imgur.com/dt48tRG.png
提前致谢。
由于它使用硬编码数据,因此有可能在上下文中启用延迟加载。
如果是这样,请在上下文中禁用延迟加载或类似这样,以便序列化到 JSON 不会从数据库加载实体。
public IEnumerable<User> ReadUsers()
{
ctx.Configuration.LazyLoadingEnabled = false;
IEnumerable<User> users = ctx.Users.ToList();
return users;
}
尝试return普通款,smth like
var logins = ctx.Users.Select(user => new FlatUserModel
{
Id = user.Id,
Name = user.UserName,
Email = user.Email
})
.ToArray();
return logins;
同时在浏览器中查看您得到的响应。
如果您的网站 return 存在内部错误并且没有调用堆栈,则您没有看到完整的异常(这使得很难准确指出您的问题)。
因此,首先要使用调用堆栈获取实际异常,您有 2 个方法。
- 调试网站:在本地启动网站或将调试器附加到本地 运行 网站。在逐步执行代码时,调试器将在遇到异常时停止,然后您将看到异常详细信息。
- 禁用自定义错误:IIS 想要保护您的内部工作,因此标准行为不是显示完整的异常。要禁用此行为,请编辑您的 web.config 并在
下添加 xml 节点
在您获得实际异常后,请使用调用堆栈和真正的内部服务器错误更新您的问题。我的猜测是您有序列化问题,可能是某种循环引用。你的解决方法是制作一个简单的 viewModel(而不是直接 return 实体)或添加序列化设置(例如 json.net 支持循环引用)。
编辑
正如怀疑的那样,序列化给你带来了困难。原因是延迟加载使用了代理创建。
您可以使用以下代码禁用代理创建(请注意,这也会禁用延迟加载)。
public IEnumerable<User> ReadUsers()
{
ctx.Configuration.ProxyCreationEnabled = false;
IEnumerable<User> users = ctx.Users.ToList();
return users;
}
如果可行,您可以考虑在上下文初始化期间禁用代理创建。
我正在构建一个 N 层应用程序,它必须发送 JSON 数据,这些数据是通过 Enity Framework 从 SQL Server 2012 读取的。
当我尝试请求一组用户时,我得到一个 "An error has occurred" 页面。它适用于硬编码数据。
这是我的代码:
public IEnumerable<User> Get()
{
IUserManager userManager = new UserManager();
return userManager.GetUsers();
}
public IEnumerable<User> GetUsers()
{
return repo.ReadUsers();
}
public IEnumerable<User> ReadUsers()
{
IEnumerable<User> users = ctx.Users.ToList();
return users;
}
"ctx" 是对 DbContext 对象的引用。
编辑:有效:
public IEnumerable<User> Get()
{
IList<User> users = new List<User>();
users.Add(new User() { FirstName = "TestPerson1" });
users.Add(new User() { FirstName = "TestPerson2" });
return users;
}
浏览器截图:http://i.imgur.com/zqG0qe0.png
编辑:完整错误(截图):http://i.imgur.com/dt48tRG.png
提前致谢。
由于它使用硬编码数据,因此有可能在上下文中启用延迟加载。
如果是这样,请在上下文中禁用延迟加载或类似这样,以便序列化到 JSON 不会从数据库加载实体。
public IEnumerable<User> ReadUsers()
{
ctx.Configuration.LazyLoadingEnabled = false;
IEnumerable<User> users = ctx.Users.ToList();
return users;
}
尝试return普通款,smth like
var logins = ctx.Users.Select(user => new FlatUserModel
{
Id = user.Id,
Name = user.UserName,
Email = user.Email
})
.ToArray();
return logins;
同时在浏览器中查看您得到的响应。
如果您的网站 return 存在内部错误并且没有调用堆栈,则您没有看到完整的异常(这使得很难准确指出您的问题)。
因此,首先要使用调用堆栈获取实际异常,您有 2 个方法。
- 调试网站:在本地启动网站或将调试器附加到本地 运行 网站。在逐步执行代码时,调试器将在遇到异常时停止,然后您将看到异常详细信息。
- 禁用自定义错误:IIS 想要保护您的内部工作,因此标准行为不是显示完整的异常。要禁用此行为,请编辑您的 web.config 并在 下添加 xml 节点
在您获得实际异常后,请使用调用堆栈和真正的内部服务器错误更新您的问题。我的猜测是您有序列化问题,可能是某种循环引用。你的解决方法是制作一个简单的 viewModel(而不是直接 return 实体)或添加序列化设置(例如 json.net 支持循环引用)。
编辑
正如怀疑的那样,序列化给你带来了困难。原因是延迟加载使用了代理创建。
您可以使用以下代码禁用代理创建(请注意,这也会禁用延迟加载)。
public IEnumerable<User> ReadUsers()
{
ctx.Configuration.ProxyCreationEnabled = false;
IEnumerable<User> users = ctx.Users.ToList();
return users;
}
如果可行,您可以考虑在上下文初始化期间禁用代理创建。