使用数据时出现问题。数据库中已更改的数据未正确显示,因为它已缓存。我认为这是WCF services配置中的问题,但在分析配置文件后,我意识到服务缓存已关闭,但MARS EF功能已启用。
MARS会话缓存
在启用MARS的情况下打开连接时,会出现逻辑会话 创建,这增加了额外的开销。 最小化开销和 增强性能,SqlClient缓存一个MARS会话 连接。
第一个也是最简单的选项是在连接设置中禁用此功能,但此过程需要很长时间,因为在我的项目中没有使用一个服务。因此,问题出现了,这个问题怎么解决?我可以强行更新数据吗?或者以某种方式从前端重置缓存?
技术堆栈: AngularJS + ASP.NET Web API(WCF)。
服务配置文件:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, Default Command Timeout=300" requirePermission="false" />
</configSections>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding closeTimeout="00:05:00" openTimeout="00:05:00" sendTimeout="00:05:00" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</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.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<connectionStrings>
<add name="MP" connectionString="data source=*;initial catalog=*;user id=*;password=*;application name=*;MultipleActiveResultSets=True;Connect Timeout=300" providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
WebApi配置文件:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<machineKey decryptionKey="*" validation="*" validationKey="*" />
</system.web>
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_*" sendTimeout="00:05:00" maxBufferSize="200000000" maxReceivedMessageSize="200000000"/>
<binding name="BasicHttpBinding_*" sendTimeout="00:05:00" maxBufferSize="200000000" maxReceivedMessageSize="200000000" />
<binding name="BasicHttpBinding_*" sendTimeout="00:05:00" maxBufferSize="2000000000" maxReceivedMessageSize="2000000000" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://*" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_*" contract="*" name="*" />
<endpoint address="http://*" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_*" contract="*" name="*" />
<endpoint address="http://*" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_*" contract="*" name="*" />
</client>
</system.serviceModel>
</configuration>
我找到了类似的question,但我想尝试以不同的方式解决问题。 我会很高兴任何想法和建议。
代码中的缓存示例:
Cache.cs:
public class CardRegistrationPartyCache
{
#region Private Members
private IUserSessionService _userSessionService = null;
#endregion
#region Constructors
public CardRegistrationPartyCache(IUserSessionService userSessionService)
{
_userSessionService = userSessionService;
}
#endregion
#region Public
public void AddOrUpdate(CardRegistrationParty crp)
{
string key = this.GetType().FullName + crp.BarcodeID.ToString();
_userSessionService.SetUserData(key, crp);
}
public CardRegistrationParty Get(int barcodeID)
{
string key = this.GetType().FullName + barcodeID.ToString();
return _userSessionService.UserData<CardRegistrationParty>(key);
}
#endregion
}
实现:
public class CardRegistrationPartyService : ApplicationService
{
#region Constructors
public CardRegistrationPartyService(IInfrastructureFactory infrastructureFactory)
: base(infrastructureFactory)
{
}
#endregion
public IEnumerable<CardRegistrationParty> GetCardRegistrationPartyListWithChecks(IList<KeyValuePair<int, GPF>> list)
{
int listCount = list == null ? 0 : list.Count();
Infrastructure.Logger.Info(String.Format("Get informations (" + listCount.ToString()) + ")");
// Caching
CardRegistrationPartyCache cache = new CardRegistrationPartyCache(Infrastructure.CreateUserSessionService());
IList<CardRegistrationParty> CardRegistrationPartyes = new List<CardRegistrationParty>();
// Check cache
foreach(KeyValuePair<int, GPF> item in list)
{
CardRegistrationParty party = cache.Get(item.Key);
if (party != null)
{
CardRegistrationPartyes.Add(party);
}
}
// Delete the keys for which information was found
if (CardRegistrationPartyes != null)
{
foreach (CardRegistrationParty p in CardRegistrationPartyes)
{
KeyValuePair<int, GPF> key = new KeyValuePair<int, GPF>(p.BarcodeID, p.Gpf);
list.Remove(key);
}
}
// If there are keys on which there was no information - we load
if ((list != null) &&(list.Count() > 0))
{
IEnumerable<CardRegistrationPartyDTO> CardRegistrationPartyesDTO = Infrastructure.CreateTestsOfEriService().GetCardRegistrationPartyListWithChecks(list.Select(m => m.Key).ToArray());
Infrastructure.Logger.Trace(String.Format("Start DTOs -> DomainObjects"));
foreach (CardRegistrationPartyDTO CardRegistrationPartyDTO in CardRegistrationPartyesDTO)
{
CardRegistrationPartyBuilder cardRegistrationPartyBuilder = new CardRegistrationPartyBuilder(CardRegistrationPartyDTO, list);
CardRegistrationParty CardRegistrationParty = cardRegistrationPartyBuilder.Build();
CardRegistrationPartyes.Add(CardRegistrationParty);
cache.AddOrUpdate(CardRegistrationParty);
}
Infrastructure.Logger.Trace(String.Format("End DTOs -> DomainObjects"));
}
return CardRegistrationPartyes;
}
}