Sql server EntityFramework因来自MVC Web Api的多个SELECT请求而失败

Sql server EntityFramework因来自MVC Web Api的多个SELECT请求而失败,sql-server,asp.net-mvc,entity-framework,asp.net-web-api,dbcontext,Sql Server,Asp.net Mvc,Entity Framework,Asp.net Web Api,Dbcontext,目前,我正在使用MVC4的Web api特性构建一个api,使用EntityFramework 4,禁用延迟加载和代理创建。因为我正在迁移一个现有的MySQL数据库,所以我使用了数据库优先策略 我的服务器运行在Windows server 2012(目前仍然是数据中心RC)上,带有IIS 8和Microsoft SQL server 2012 我认为我遇到的问题不是“功能性”类别,而是“性能”类别。在示例中,我有一个Person对象。此对象具有子对象列表和城市对象(包含城市的基本信息): 首先,

目前,我正在使用MVC4的Web api特性构建一个api,使用EntityFramework 4,禁用延迟加载和代理创建。因为我正在迁移一个现有的MySQL数据库,所以我使用了数据库优先策略

我的服务器运行在Windows server 2012(目前仍然是数据中心RC)上,带有IIS 8和Microsoft SQL server 2012

我认为我遇到的问题不是“功能性”类别,而是“性能”类别。在示例中,我有一个Person对象。此对象具有子对象列表和城市对象(包含城市的基本信息):

首先,我希望有人能给我一些信息,如果这是在Web Api中使用EntityFramework的正确方法,尤其是db对象的创建。我读过多篇关于创建所谓的存储库类的文章,但我选择不这样做

现在,我提出这个问题是为了解决这个问题; 当我执行一个请求来获取ID为1的人的信息时,一切都很顺利。同时将GetChildren和getCity参数设置为true。(这适用于数据库中的所有可用人员)。 但是,这是在一次执行一个请求时发生的。当我使用Fiddler快速执行相同的请求时,在一对请求之后,500个错误开始出现。然后几个请求再次正常,然后它失败了几次,等等

当请求失败时,将显示以下错误消息之一: 不允许新事务,因为会话中正在运行其他线程。 或 无法执行事务操作,因为有挂起的请求正在处理此事务

这实际上说明他不能创建一个新的事务,因为在这个会话中有其他线程,而且它不能向事务添加请求,因为有一个队列准备就绪

希望您理解这真的很烦人,因为当api上线并被多个用户同时使用时,也可能发生这种情况

有人知道如何解决上述错误吗?请检查我上面的实现示例,可能它不是最优的:)

提前谢谢

您可以通过在连接字符串中添加“MultipleActiveResultSets=True”来启用,以解决此问题。您必须启用MARS的原因是您在单个连接(即DbContext)上执行多个查询

另一种更好的方法是不启用MARS,而是通过这样做来优化您的操作以执行单个查询(Entityframework)。这具有调用单个查询而不是3个查询的优点(最坏情况)

[DataContract(IsReference = true)]
public partial class Person
{
    public Person()
    {
        this.Children = new HashSet<Children>();
    }

    [DataMember]
    public int ID { get; set; }
    [DataMember]
    public int ParentID { get; set; }
    [DataMember]
    public int CityID { get; set; }
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public int Age { get; set; }

    [DataMember]
    public virtual ICollection<Person> Children { get; set; }
    [DataMember]
    public City City { get; set; }
}

[DataContract(IsReference = true)]
public partial class City
{
    [DataMember]
    public int ID { get; set; }
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public int Residents { get; set; }
}

Note: These classes are generated by EntityFramework/DBContext
public class PersonsController : ApiController
{
    private MyEntities db = new MyEntities();

    [HttpGet]
    public Person Get(int id, bool getChildren = false, bool getCity = false)
    {
        Person person = this.db.Persons.SingleOrDefault(p => p.ID == id);
        if (person == null)
        {
            throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
        }

        if (getChildren)
        {
            person.Children = this.db.Persons.Where(c => c.ParentID == person.ID)
        }

        if (getCity)
        {
            person.Customer = this.db.Cities.SingleOrDefault(r => r.ID == person.CityID);
        }

        return person;
    }
}
public class PersonsController : ApiController
{
    private MyEntities db = new MyEntities();

    public Person Get(int id, bool getChildren = false, bool getCity = false)
    {
        var people = this.db.Persons;

        if(getChildren)
        {
            people = people.Include("Children");
        }

        if(getCity)
        {
            people = people.Include("City");
        }

        Person person = people.SingleOrDefault(p => p.ID == id);
        if (person == null)
        {
            throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
        }

        return person;
    }
}