أفضل طريقة لمعرفة ما اذا كان يوجد كائن في إطار الكيان؟
-
05-07-2019 - |
سؤال
ما هي أفضل طريقة لمعرفة ما اذا كان يوجد كائن في قاعدة البيانات من جهة نظر الأداء؟ أنا باستخدام إطار الكيان 1.0 (ASP.NET 3.5 SP1).
المحلول
إذا كنت لا تريد تنفيذ SQL مباشرة، فإن أفضل طريقة هي استخدام <لأ href = "http://msdn.microsoft.com/en-us/library/system.linq.queryable.any.aspx "يختلط =" noreferrer "> أي () . وذلك لأن أي) سيعود (بمجرد أن يجد المباراة. وثمة خيار آخر هو عدد () ، ولكن هذا قد تحتاج إلى التحقق من كل صف قبل أن يعود.
وهنا مثال لكيفية استخدامه:
if (context.MyEntity.Any(o => o.Id == idToMatch))
{
// Match!
}
وفي vb.net
If context.MyEntity.Any(function(o) o.Id = idToMatch) Then
' Match!
End If
نصائح أخرى
من وجهة نظر الأداء، وأعتقد أن استعلام SQL مباشرة باستخدام المشرقية أن القيادة يكون مناسبا. انظر هنا لكيفية تنفيذ SQL مباشرة في إطار الكيان: <لأ href = "http://blogs.microsoft.co.il/blogs/gilf/archive/2009/11/25/execute-t-sql-statements-in -entity-إطار 4.aspx "يختلط =" noreferrer "> http://blogs.microsoft.co.il/blogs/gilf/archive/2009/11/25/execute-t-sql-statements-in-entity -framework-4.aspx
وكان لي لإدارة السيناريو حيث بلغت نسبة التكرارات التي قدمت في سجلات بيانات جديدة وعالية جدا، وذلك وتبذل عدة آلاف من المكالمات قاعدة بيانات للتحقق من التكرارات (حتى وحدة المعالجة المركزية أرسلت الكثير من الوقت في 100 ٪). في النهاية قررت أن تبقي 100،000 السجلات مشاركة مؤقتا في الذاكرة. بهذه الطريقة أتمكن من التحقق من التكرارات ضد السجلات المخزنة مؤقتا الذي سريع للغاية بالمقارنة مع استعلام LINQ على قاعدة بيانات SQL، ومن ثم كتابة أي سجلات جديدة حقا إلى قاعدة البيانات (وكذلك إضافتها إلى ذاكرة التخزين المؤقت البيانات، وأنا أيضا فرزها وقلص للحفاظ على طوله التحكم).
لاحظ أن البيانات الخام كان ملف CSV التي تحتوي على العديد من السجلات الفردية التي كان لا بد من تحليل. السجلات في كل ملف على التوالي (والذي جاء بمعدل حوالي 1 في كل 5 دقائق) تتداخل إلى حد كبير، وبالتالي فإن نسبة عالية من التكرارات.
وباختصار، إذا كنت قد قتية البيانات الخام القادمة، الى حد كبير في النظام، ثم باستخدام ذاكرة التخزين المؤقت قد تساعد على التحقق من سجل الازدواجية.
وأنا أعلم أن هذا هو موضوع قديم جدا ولكن مجرد طارئ شخص مثلي يحتاج هذا الحل ولكن في VB.NET هنا ما كنت قاعدة على إجابات أعلاه.
Private Function ValidateUniquePayroll(PropertyToCheck As String) As Boolean
// Return true if Username is Unique
Dim rtnValue = False
Dim context = New CPMModel.CPMEntities
If (context.Employees.Any()) Then ' Check if there are "any" records in the Employee table
Dim employee = From c In context.Employees Select c.PayrollNumber ' Select just the PayrollNumber column to work with
For Each item As Object In employee ' Loop through each employee in the Employees entity
If (item = PropertyToCheck) Then ' Check if PayrollNumber in current row matches PropertyToCheck
// Found a match, throw exception and return False
rtnValue = False
Exit For
Else
// No matches, return True (Unique)
rtnValue = True
End If
Next
Else
// The is currently no employees in the person entity so return True (Unqiue)
rtnValue = True
End If
Return rtnValue
End Function
وكان لي بعض المشاكل مع هذا - يتكون بلدي EntityKey من ثلاث خصائص (PK مع 3 أعمدة) وأنا لا أريد أن تحقق كل من الأعمدة لأن ذلك سيكون القبيح. فكرت في الحل الذي يعمل كل الوقت مع جميع الكيانات.
وهناك سبب آخر لهذا أنا لا أحب أن يمسك UpdateExceptions في كل مرة.
وهناك حاجة إلى القليل من التفكير للحصول على قيم الخصائص الرئيسية.
ويتم تنفيذ التعليمات البرمجية كما امتدادا لتبسيط الاستخدام على النحو التالي:
context.EntityExists<MyEntityType>(item);
وإلقاء نظرة:
public static bool EntityExists<T>(this ObjectContext context, T entity)
where T : EntityObject
{
object value;
var entityKeyValues = new List<KeyValuePair<string, object>>();
var objectSet = context.CreateObjectSet<T>().EntitySet;
foreach (var member in objectSet.ElementType.KeyMembers)
{
var info = entity.GetType().GetProperty(member.Name);
var tempValue = info.GetValue(entity, null);
var pair = new KeyValuePair<string, object>(member.Name, tempValue);
entityKeyValues.Add(pair);
}
var key = new EntityKey(objectSet.EntityContainer.Name + "." + objectSet.Name, entityKeyValues);
if (context.TryGetObjectByKey(key, out value))
{
return value != null;
}
return false;
}
وأنا فقط معرفة ما اذا كان الهدف من ذلك هو باطل، وأنها تعمل 100٪ بالنسبة لي
try
{
var ID = Convert.ToInt32(Request.Params["ID"]);
var Cert = (from cert in db.TblCompCertUploads where cert.CertID == ID select cert).FirstOrDefault();
if (Cert != null)
{
db.TblCompCertUploads.DeleteObject(Cert);
db.SaveChanges();
ViewBag.Msg = "Deleted Successfully";
}
else
{
ViewBag.Msg = "Not Found !!";
}
}
catch
{
ViewBag.Msg = "Something Went wrong";
}
لماذا لا نفعل ذلك؟
var result= ctx.table.Where(x => x.UserName == "Value").FirstOrDefault();
if(result?.field == value)
{
// Match!
}