实体框架:现有连接被远程主机强行关闭

时间:2019-05-25 17:58:04

标签: c# sql-server wpf entity-framework

我将Entity Framework 6.2.0与WCF服务托管在IIS中。尝试热切加载相关表数据时出现此错误。我有两个由Product连接的表CategoryCategoryID

尝试获取产品数据及其相关的category Name,但收到该错误(过去24小时内,我几乎尝试了Web上的所有解决方案)。

public List<Product> GetAllProducts(int start, int end)
{
    return _context.Products.Include(x=>x.Category).ToList();
}  

我还将以下属性设置为false。

public Intelliventory_DBEntities()
    : base("name=Intelliventory_DBEntities")
{
    this.Configuration.ProxyCreationEnabled = false;
    this.Configuration.LazyLoadingEnabled = false;
}  

App.config

<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IIntelliventoryService" 
                         closeTimeout="10:01:00" openTimeout="10:01:00" 
                         receiveTimeout="10:10:00" sendTimeout="10:01:00" 
                         allowCookies="false" bypassProxyOnLocal="false" 
                         maxBufferPoolSize="2147483647" 
                         maxReceivedMessageSize="2147483647"
                         useDefaultWebProxy="true">
                    <readerQuotas maxDepth="2147483647" 
                                  maxStringContentLength="2147483647"
                                  maxArrayLength="2147483647"    
                                  maxBytesPerRead="2147483647"
                                  maxNameTableCharCount="2147483647" />
                </binding>
            </basicHttpBinding>
        </bindings>
        <behaviors>
            <endpointBehaviors>
                <behavior name="ServiceBehavior">
                     <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
                </behavior>
            </endpointBehaviors>
        </behaviors>
        <client>
            <endpoint name="BasicHttpBinding_IIntelliventoryService" 
                address="http://localhost:5050/IntelliventoryService.svc"
                behaviorConfiguration="ServiceBehavior"  
                binding="basicHttpBinding" 
                bindingConfiguration="BasicHttpBinding_IIntelliventoryService"
                contract="IntelliventoryService.IIntelliventoryService" />
        </client>
    </system.serviceModel>
</configuration>  

Web.Config

<configuration>
    <configSections>
        <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </configSections>
    <appSettings>
        <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
    </appSettings>
    <system.web>
        <compilation debug="true" targetFramework="4.8" />
        <httpRuntime targetFramework="4.8" />
    </system.web>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IIntelliventoryService" 
                         closeTimeout="10:01:00" openTimeout="10:01:00" 
                         receiveTimeout="10:10:00" sendTimeout="10:01:00" 
                         allowCookies="false" bypassProxyOnLocal="false" 
                         maxBufferPoolSize="2147483647" 
                         maxReceivedMessageSize="2147483647"
                         useDefaultWebProxy="true">
                    <readerQuotas maxDepth="2147483647" 
                                  maxStringContentLength="2147483647"
                                  maxArrayLength="2147483647" 
                                  maxBytesPerRead="2147483647"
                                  maxNameTableCharCount="2147483647" />
                </binding>
            </basicHttpBinding>
        </bindings>
        <behaviors>
            <serviceBehaviors>
                <behavior>
                    <dataContractSerializer maxItemsInObjectGraph ="2147483647"/>
                    <serviceThrottling maxConcurrentCalls="16" maxConcurrentInstances="26" maxConcurrentSessions="10" />
                    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="true" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <protocolMapping>
            <add binding="basicHttpsBinding" scheme="https" />
        </protocolMapping>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
        </system.serviceModel>
    <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
    <directoryBrowse enabled="true" />
  </system.webServer>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="mssqllocaldb" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
<connectionStrings>
  <add name="Intelliventory_DBEntities" 
                        connectionString="metadata=res://*/ADOModel.csdl|res://*/ADOModel.ssdl|res://*/ADOModel.msl;provider=System.Data.SqlClient;
                        provider connection string=&quot;data source=RAO-HAMMAS-PC;initial catalog=Intelliventory_DB;persist security info=True;
                        user id=admin;password=admin;MultipleActiveResultSets=True;App=EntityFramework&quot;" 
                        providerName="System.Data.EntityClient" />
</connectionStrings></configuration>  

当我不希望加载类别表时,我不会收到此错误。

另外,如果我尝试仅加载特定列,则会收到此错误。

_context.Products.Include(x=>x.Category.CategoryName).ToList();
  

指定的包含路径无效。 EntityType'Intelliventory_DBModel.Category'未声明导航

Db上下文中的类别表

public int CategoryID { get; set; }
public string CategoryName { get; set; } 

Db上下文中的产品表

public partial class Product
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Product()
    {
        this.Purchases = new HashSet<Purchase>();
    }

    public int ProductID { get; set; }
    public string ProductName { get; set; }
    public int CategoryID { get; set; }
    public System.DateTime Date { get; set; }
    public double Quantity { get; set; }
    public string Model { get; set; }
    public string Details { get; set; }
    public double SellPrice { get; set; }
    public double PurchasePrice { get; set; }
    public int SupplierID { get; set; }
    public Nullable<double> PaidAmount { get; set; }
    public Nullable<int> NoOfSales { get; set; }
    public Nullable<double> DueAmountToPay { get; set; }
    public Nullable<System.DateTime> ExpiryDate { get; set; }

    public virtual Category Category { get; set; }
    public virtual Supplier Supplier { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Purchase> Purchases { get; set; }
}  

正如 @Andy 所指出的,类别不是ICollection,供应商也不是ICollection,而采购则是ICollection。但这都是自动生成的。我做错什么了吗 ?

enter image description here

这是在数据获取事件(SSMS直播事件)期间发生的事情

enter image description here

更新:我创建了一个控制台应用程序,并直接使用了EF,它可以正常工作

enter image description here

  

但是当我再次在此控制台应用中使用WCF来获取产品时,我也遇到了同样的错误!

堆栈异常跟踪

System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary()
   at Intelliventory.IntelliventoryService.GetAllProductsCompletedEventArgs.get_Result() in E:\\2- Development\\2-NATIVE WORLD\\Projects\\Intelliventory\\Intelliventory\\Connected Services\\IntelliventoryService\\Reference.cs:line 321
   at Intelliventory.UserControls.ProductControl.ClientOnGetAllProductsCompleted(Object sender, GetAllProductsCompletedEventArgs e) in E:\\2- Development\\2-NATIVE WORLD\\Projects\\Intelliventory\\Intelliventory\\UserControls\\ProductControl.xaml.cs:line 89
   at Intelliventory.IntelliventoryService.IntelliventoryServiceClient.OnGetAllProductsCompleted(Object state) in E:\\2- Development\\2-NATIVE WORLD\\Projects\\Intelliventory\\Intelliventory\\Connected Services\\IntelliventoryService\\Reference.cs:line 1082
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
   at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at System.Windows.Application.Run(Window window)
   at System.Windows.Application.Run()
   at Intelliventory.App.Main()  

所有三个例外!

enter image description here enter image description here enter image description here

更新:我已经获得了异常详细信息(类别包含循环)

  

'IntelliventoryWcfService.Category'包含循环,如果禁用了引用跟踪,则无法序列化

enter image description here

2 个答案:

答案 0 :(得分:1)

所以最后我在一些非常好的人的帮助下找到并解决了这个问题:)
问题是

  

'IntelliventoryWcfService.Category'包含循环,如果禁用了引用跟踪,则无法序列化

因此,基本上类别包含导致服务器断开连接的循环或循环引用。解决方案是将[DataContract(IsReference = true)]放在Category类上。因此,该类现在看起来像这样。

using System.Runtime.Serialization;

[DataContract(IsReference = true)]
public partial class Category
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Category()
    {
        this.Products = new HashSet<Product>();
    }
    [DataMember]
    public int CategoryID { get; set; }
    [DataMember]
    public string CategoryName { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    [DataMember]
    public virtual ICollection<Product> Products { get; set; }
}  

帮助参考http://themvcclub.blogspot.com/2014/11/how-to-fix-WCF-Web-API-Error-contains-cycles-and-cannot-be-serialized-if-reference-tracking-is-disabled.html

答案 1 :(得分:0)

应该包含是包含您的集合的属性的名称。

代替

  Products.Include(x=>x.Category.Category)

我认为应该是:

  Products.Include(x=>x.Category)

  Products.Include("Category")

https://docs.microsoft.com/en-us/ef/ef6/querying/related-data

似乎只有一个类别与产品相关联,因此它应该是标量属性。