Entity Frameworkを使用して100個のエンティティ(およびその子要素)を大量に挿入しようとしています。ローカルホスト上にあるデータベースにバルクを挿入するのに約3秒かかり、同じイントラネット上にあるリモートデータベースに同じバルクを挿入しようとすると約300秒かかります。EF SaveChanges()はローカルホストでは非常に高速ですが、リモートデータベースでは非常に遅い
リモートデータベースとSaveChanges(ローカルホスト)を実行しているコンピュータとの間の接続は遅くありません。
私は、ファイアウォールやリモートSQLサーバー上の構成と関係があると推測しています。どうすれば問題をさらに調査することができますか?
これはコードです:
public void SaveProcessedProperties(object properties)
{
var propertiesToPersist = properties as List<Ejendom>;
using (var db = new TinglysUdv_UdpakEntities())
{
db.Configuration.AutoDetectChangesEnabled = false;
db.Configuration.LazyLoadingEnabled = false;
try
{
foreach (var property in propertiesToPersist)
{
#region Haeftelse
if (property.Haeftelse.Any())
{
foreach (var liability in property.Haeftelse)
{
if (liability.AttachDocument)
{
var existingDoc = db.Dokument.Find(liability.DokumentIdentifikator, liability.DokumentRevisionNummer);
if (existingDoc == null)
{
Dokument dbDoc;
if (DocumentExists(db, liability.DokumentIdentifikator, liability.DokumentRevisionNummer, out dbDoc))
{
existingDoc = dbDoc;
}
}
if (existingDoc != null)
{
liability.Dokument = existingDoc;
}
else
{
var dok = new Dokument()
{
DokumentIdentifikator = liability.DokumentIdentifikator,
DokumentRevisionNummer = liability.DokumentRevisionNummer
};
db.Dokument.Attach(dok);
liability.Dokument = dok;
}
}
}
}
#endregion
#region Adkomst
if (property.Adkomst.Any())
{
foreach (var claim in property.Adkomst)
{
if (claim.AttachDocument)
{
var existingDoc = db.Dokument.Find(claim.DokumentIdentifikator, claim.DokumentRevisionNummer);
if (existingDoc == null)
{
Dokument dbDoc;
if (DocumentExists(db, claim.DokumentIdentifikator, claim.DokumentRevisionNummer, out dbDoc))
{
existingDoc = dbDoc;
}
}
if (existingDoc != null)
{
claim.Dokument = existingDoc;
}
else
{
var dok = new Dokument()
{
DokumentIdentifikator = claim.DokumentIdentifikator,
DokumentRevisionNummer = claim.DokumentRevisionNummer
};
db.Dokument.Attach(dok);
claim.Dokument = dok;
}
}
}
}
#endregion
#region Servitut
if (property.Servitut.Any())
{
foreach (var easement in property.Servitut)
{
if (easement.AttachDocument)
{
var existingDoc = db.Dokument.Find(easement.DokumentIdentifikator, easement.DokumentRevisionNummer);
if (existingDoc == null)
{
Dokument dbDoc;
if (DocumentExists(db, easement.DokumentIdentifikator, easement.DokumentRevisionNummer, out dbDoc))
{
existingDoc = dbDoc;
}
}
if (existingDoc != null)
{
easement.Dokument = existingDoc;
}
else
{
var dok = new Dokument()
{
DokumentIdentifikator = easement.DokumentIdentifikator,
DokumentRevisionNummer = easement.DokumentRevisionNummer
};
db.Dokument.Attach(dok);
easement.Dokument = dok;
}
}
}
}
#endregion
db.Ejendom.Add(property);
}
db.SaveChanges();
}
catch (Exception ex)
{
throw;
}
}
}
private bool DocumentExists(TinglysUdv_UdpakEntities db, Guid documentIdentifier, int documentRevision, out Dokument dbDocument)
{
var documentExists = false;
dbDocument = db.Dokument.FirstOrDefault(x => x.DokumentIdentifikator == documentIdentifier && x.DokumentRevisionNummer == documentRevision);
if (dbDocument != null)
{
documentExists = true;
}
return documentExists;
}
はEntity Framework Profilerのトレイル版を手に入れたし、コードをプロファイリング。ここでの結果は次のとおりです。
私は、次の警告を得た特定のコンテキストについては:
INSERT [dbo].[Respekt]
([RettighedIdentifikator],
[RespektServitutDato],
[Resp_Haeft_Fremtid_id])
VALUES ('1425fd57-042a-4649-a344-0f386b59e400' /* @0 - [RettighedIdentifikator] */,
NULL,
NULL)
--//////////////////////////////////////////////////
SELECT [Respekt_id]
FROM [dbo].[Respekt]
WHERE @@ROWCOUNT > 0
AND [Respekt_id] = scope_identity()
は何があります:EFが作っているN + 1クエリの
例保存しようとしているエンティティの量を減らす以外に、私はこれについて行うことができますか?
使用しているコードを表示できますか?それは、インサートがネットワーク上でより多くのオーバヘッドを引き起こすであろう一度に1つずつではなく、1つのことである可能性があります。 – Matthew
私はコード – Kenci
で質問を更新しました。ありがとうございました。私の考えが有効でないようにループを保存しているように見えます(同様の問題がありましたが、保存がループにありました)。この問題で幸運。 – Matthew