Odpowiedzi:
Jeśli nie chcesz bezpośrednio wykonywać kodu SQL, najlepszym sposobem jest użycie Any () . Dzieje się tak, ponieważ Any () powróci, gdy tylko znajdzie dopasowanie. Inną opcją jest Count () , ale może to wymagać sprawdzenia każdego wiersza przed zwróceniem.
Oto przykład, jak go używać:
if (context.MyEntity.Any(o => o.Id == idToMatch))
{
// Match!
}
Oraz w vb.net
If context.MyEntity.Any(function(o) o.Id = idToMatch) Then
' Match!
End If
T
do interfejsu, który jest IEnumerable
i zwracasz obiekty, które zawierają znak Id
, powinieneś być w stanie użyć swojej funkcji ogólnej IsExists<T>()
.
Z punktu widzenia wydajności wydaje mi się, że odpowiednie byłoby bezpośrednie zapytanie SQL za pomocą polecenia EXISTS . Zobacz tutaj, jak wykonać SQL bezpośrednio w Entity Framework: http://blogs.microsoft.co.il/blogs/gilf/archive/2009/11/25/execute-t-sql-statements-in-entity-framework- 4.aspx
Musiałem poradzić sobie ze scenariuszem, w którym procent duplikatów dostarczanych w nowych rekordach danych był bardzo wysoki i tak wiele tysięcy wywołań bazy danych było wykonywanych w celu sprawdzenia duplikatów (więc procesor wysyłał dużo czasu na 100%). Ostatecznie postanowiłem zachować ostatnie 100 000 rekordów w pamięci podręcznej. W ten sposób mogłem sprawdzić, czy nie ma duplikatów w zapisach w pamięci podręcznej, co było niezwykle szybkie w porównaniu z zapytaniem LINQ do bazy danych SQL, a następnie zapisać wszelkie autentycznie nowe rekordy do bazy danych (a także dodać je do pamięci podręcznej danych, co również posortowane i przycięte, aby zachować odpowiednią długość).
Zwróć uwagę, że nieprzetworzone dane były plikiem CSV zawierającym wiele pojedynczych rekordów, które trzeba było przeanalizować. Rekordy w każdym kolejnym pliku (które pojawiały się w tempie około 1 na 5 minut) znacznie się pokrywały, stąd wysoki procent duplikatów.
Krótko mówiąc, jeśli napływają surowe dane ze znacznikami czasu, prawie w porządku, użycie pamięci podręcznej może pomóc w sprawdzaniu duplikacji rekordów.
Wiem, że to bardzo stary wątek, ale po prostu na wypadek, gdyby ktoś taki jak ja potrzebował tego rozwiązania, ale w VB.NET oto, czego użyłem w oparciu o powyższe odpowiedzi.
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
Miałem z tym problem - mój EntityKey składa się z trzech właściwości (PK z 3 kolumnami) i nie chciałem sprawdzać każdej z kolumn, ponieważ byłoby to brzydkie. Pomyślałem o rozwiązaniu, które działa cały czas ze wszystkimi podmiotami.
Innym powodem jest to, że nie lubię za każdym razem łapać UpdateExceptions.
Potrzebna jest odrobina refleksji, aby uzyskać wartości właściwości klucza.
Kod jest zaimplementowany jako rozszerzenie, aby uprościć użytkowanie, jako:
context.EntityExists<MyEntityType>(item);
Spójrz:
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;
}
Po prostu sprawdzam, czy obiekt jest pusty, u mnie działa w 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";
}
Dlaczego tego nie zrobisz?
var result= ctx.table.Where(x => x.UserName == "Value").FirstOrDefault();
if(result?.field == value)
{
// Match!
}
Niezależnie od tego, jaki jest twój obiekt i dla jakiej tabeli w bazie danych, jedyne, co musisz mieć, to klucz podstawowy w obiekcie.
var dbValue = EntityObject.Entry(obj).GetDatabaseValues();
if (dbValue == null)
{
Don't exist
}
Dim dbValue = EntityObject.Entry(obj).GetDatabaseValues()
If dbValue Is Nothing Then
Don't exist
End If