1

My domain class:

public class Address
{
    [Key]
    public virtual string AddressId { get; set; }
    public virtual string Address { get; set; }
}

In my MVC controller I want to check the given Address exist, before I insert.

public ActionResult Create(Address address)
{
   if (ModelState.IsValid)
   {
      if (db.Addresses.Any(a => a.AddressId == address.AddressId)) // how I do it now
      {
         ModelState.AddModelError(string.Empty, "Address Id already exists!");
      }
      else
      {
         db.Addresses.Add(address);
         db.SaveChanges();
         return RedirectToAction("Index");
      }
   }
}

But there are lot of other domain classes in my project and I want to do the same check again and again.

My question is I want to write a generic method in my Db context class to perform this check. (looks like below or similar)

public bool Exists(object) {
    // return true if exist
}

i.e. a method which I can call like this:

db.Exists(address)

Thanks!

Para Kan
  • 121
  • 3
  • 12

1 Answers1

4

You could use generics and do something like the following:

public class YourDbContext : DbContext
{
    ...

    public bool Exists<TEntity>(object id)
        where TEntity : class
    {
        var dbSet = Set<TEntity>();
        var entity = dbSet.Find(id);
        return entity != null;
    }

Which you'd then use like:

db.Exists<Address>(address.AddressId);

Using Find isn't the most efficient way to handle this, but it has the key benefit that you're not required to know what the actual primary key property on the class is, which would greatly complicate this method. For example, Address has AddressId, but Foo might have FooId.

UPDATE

Since ultimately this just uses Find under the hood, you just have to modify the method slightly to be able to take multiple parameters. Find handles composite keys by allowing one more parameters to be passed to it. But bear in mind, the the order matters and must align with the key order you specified when configuring your entity.

public bool Exists<TEntity>(params object[] keys)
    where TEntity : class
{
    var dbSet = Set<TEntity>();
    var entity = dbSet.Find(keys);
    return entity != null;
}
Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • Im getting an error at this point `Set` `'System.Data.Entity.DbContext.Set()' is a 'method', which is not valid in the given context`. My DbContext looks like this: `public class MyDbContext : IdentityDbContext` – Para Kan Aug 09 '14 at 14:42
  • Sorry about that. Moving too quickly and forgot a step. – Chris Pratt Aug 09 '14 at 14:46
  • Thanks @Chris, it works! var dbSet = Set<`Entity`>(); should be var dbSet = Set<`TEntity`>(); – Para Kan Aug 09 '14 at 14:53
  • What if my entity has more than one key? At the end of this [PAGE](http://stackoverflow.com/questions/1802286/best-way-to-check-if-object-exists-in-entity-framework) (the last answer) there is a solution. But I couldn't convert the code to use it with `DbContext`. – Para Kan Aug 09 '14 at 16:53