我已经设置了一个MVC 4.0 Web API,以便为用户提供从我的数据库返回信息的请求。
我已经设置并运行了所有控制器,auth和接口等,但是在将请求的数据返回给用户时遇到了问题。
我应该注意我的函数使用并返回EDM对象而不是我自己创建的对象作为模型。
以下是用户从数据库中GET
产品的示例函数。
public Product Get(int id)
{
Product product = null;
try
{
using (DataSQLEntities db = new DataSQLEntities())
{
product = (from it in db.Products
where it.ProductID == id
select it).First();
}
}
catch (ArgumentNullException)
{
var resp = new HttpResponseMessage(HttpStatusCode.NotFound)
{
Content = new StringContent(string.Format("No product with id: {0} could be found", id)),
ReasonPhrase = "Id not found"
};
throw new HttpResponseException(resp);
}
return product;
}
如果我在返回之前断点,该函数可以工作并从数据库返回正确的产品,但是,当通过API控制器返回产品进行序列化时(Json或XML,根据用户请求)我得到了一个以下错误:
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection
。
这是因为我在我的代码中使用了using()
语句,并且当序列化程序试图获取'要序列化的对象中的字段的值,它可能需要访问数据库,因为该值是对数据库的另一部分的引用。但是由于DB的范围现在已经消失,它自然会抛出这个错误。
我看起来高低,以防止产品'包括任何参考文献的对象,但似乎没有什么知识可以用于此。
我尝试过其他更改,例如删除Using语句,但我真的不想这样做,当我这样做时,由于外键等原因,它会返回太多数据。
我试图改变LINQ以试图解决这个问题(见下文),但没有运气,进一步的错误或完全无法管理的代码。我非常感谢任何有关如何避免在产品中返回引用的见解或帮助。
替代LINQ:
这是完全无法管理且可怕的代码,但有效
var temp = (from it in db.Products
where it.ProductID == id
select new
{
Name = it.Name,
Description = it.Description,
ProductID = it.ProductID
//Many other fields
}
return new Product()
{
Name = temp.Name,
Description = temp.Description,
ProductID = temp.ProductID
//Many other fields
}
这没有用(不是我预期的)
Product product = null;
//using here
Product temp = (from it in db.Products
where it.ProductID == id
select it).First();
product = temp;
//end using
return product
如果有人能够告诉我如何获取EDM对象的字段列表,例如使用反射或类似的普通对象,我可以编写一个函数来循环使用引用的字段或最小化代码第一个替代LINQ代码片段。
非常感谢
答案 0 :(得分:2)
您是否尝试过禁用延迟加载?
db.ContextOptions.LazyLoadingEnabled = false;
答案 1 :(得分:0)
这是您应该创建视图模型类而不直接公开域模型的原因之一。