views:

79

answers:

2

Hi

What would be the best way to check if a record exists in a table. What happens is the user types the same name and I need to see if it is in the database. The thing is that I would like to do it on the Repository base class that uses generics. So I can not go Entity.Name.

public void Save(T item)
        {
            Table<T> table = _db.GetTable<T>();
            table.InsertOnSubmit(item);
            _db.SubmitChanges();
        }

This will not work as the items is not exactly the same

 if (!table.Contains(item))
            {
                table.InsertOnSubmit(item);
            }

Thanks

A: 

This will give you a collection of the Identity members you could do a check on the primary key of your item is contained in the collection

_db.Mapping.GetTable(T).RowType.IdentityMembers
Stephen Binns
_db.Mapping.GetTable(T).RowType.IdentityMembers this will not work'T' is a 'type parameter' but is used like a 'variable'
how about?_db.Mapping.GetTable(item.GetType()).RowType.IdentityMembers
Stephen Binns
A: 

If you have to use just DataContext, then you can build the expression manually. In this case I'm using a selector expression, but reflection on a property-name (i.e. "Name") would do just as well:

static void Main()
{
    string knownName;
    using (DataClasses1DataContext ctx = new DataClasses1DataContext())
    {
        knownName = ctx.Customers.First().CompanyName;
    }
    using (DataContext ctx = new DataClasses1DataContext())
    {
        Console.WriteLine(ctx.Any<Customer, string>(
             cust => cust.CompanyName, "none-such"));
        Console.WriteLine(ctx.Any<Customer, string>(
             cust => cust.CompanyName, knownName));
    }
}

static bool Any<TEntity, TValue>(
    this DataContext ctx,
    Expression<Func<TEntity, TValue>> selector,
    TValue value)
    where TEntity : class
{
    var lambda =
        Expression.Lambda<Func<TEntity, bool>>(
            Expression.Equal(
                selector.Body,
                Expression.Constant(value, typeof(TValue))),
                selector.Parameters);
    return ctx.GetTable<TEntity>().Any(lambda);
}


The string-based approach would be:

using (DataContext ctx = new DataClasses1DataContext())
{
    Console.WriteLine(ctx.Any<Customer, string>("CompanyName", "none-such"));
    Console.WriteLine(ctx.Any<Customer, string>("CompanyName", knownName));
}
...
static bool Any<TEntity, TValue>(
    this DataContext ctx,
    string propertyOrFieldName,
    TValue value)
    where TEntity : class
{
    var param = Expression.Parameter(typeof(TEntity), "row");

    var lambda =
        Expression.Lambda<Func<TEntity, bool>>(
            Expression.Equal(
                Expression.PropertyOrField(param, propertyOrFieldName),
                Expression.Constant(value, typeof(TValue))),
                param);
    return ctx.GetTable<TEntity>().Any(lambda);
}
Marc Gravell
Marc the thing is I do not want to go and specify (CompanyName)