What methods can I use Find, FirstOrDefault, Any....
public virtual void Add(T entity)
{
using (MovieAppContext _context = new MovieAppContext())
{
var record = _context.Set<T>().Find(entity); // does not work I got e
if (record == null)
{
_context.Set<T>().Add(entity);
_context.SaveChanges();
}
}
}
Given your scope here, DbSet<T>.Find<T>(params object[])
is probably not the method you should be using.
The following solution uses IQueryable<T>.Any<T>(Expression<Func<T, bool>>)
, a Linq Extension Method that accepts a Predicate\Function.
using (MovieAppContext _context = new MovieAppContext())
{
bool queryResult = _context.Set<T>().Any((e) => e.Name.Equals(entity.Name, StringComparison.OrdinalIgnoreCase));
if (queryResult)
{
_context.Set<T>().Add(entity);
_context.SaveChanges();
}
}
Here, we are defining an anonymous function delegate, Func<T, bool>
, that is in turn being used to define a Linq Expression, Expression<Func<T, bool>>
.
I defined this function predicate expression to evaluate on the entity names (a made-up property of this type; that in this example portrays a unique constraint.)
Also, an alternative to using anonymous functions declaration for this expression is to declare it, then pass it.
That looks like the following:
...
Expression<Func<T, bool>> WhereEntityNameMatches = (e) => e.Name.Equals(entity.Name, StringComparison.OrdinalIgnoreCase));
bool queryResult = _context.Set<T>().Any(WhereEntityNameMatches);
...
Which may help out with reusability and scope considerations.
For consideration, An alternative here would be to not attempt the query lookup and check at all.
Instead, you would do a try-catch for DbUpdateException
in the attempt to save changes after\following this Add
operation.
try
{
_context.Set<T>().Add(entity);
_context.SaveChanges();
}
catch (DbUpdateException)
{
var isRaisedByUniqueIndexOrConstraint = new[] { "2601", "2627" }.Contains(ex.GetBaseException().Data["HelpLink.EvtID"]) ?? false;
if (!isRaisedByUniqueIndexOrConstraint)
throw;
// Could suppress and\or handle attempted duplicate record adding
}
This relies on those index\constraints existing, so you would first define a Unique Index on the column(s) (as well as your entity type using Data Annotations: IndexAttribute
).
Part of this answer\solution purposes getting the Error Number from ADO.NET SqlClient Base Exception to further scope and qualify the cause of exception. The Error Numbers, "2601", "2627"
, are hard-coded in this example.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.