Generic GetById

Posts   
 
    
rboarman
User
Posts: 83
Joined: 01-Feb-2005
# Posted on: 08-May-2010 02:36:05   

Hello,

I am trying to come up with a GetById method for a generic repository wrapper. My PK ids can be ints or guids. For example, I found something similar:


        public override T GetById(object id)
        {
            var itemParameter = Expression.Parameter(typeof(T), "item");

            var whereExpression = Expression.Lambda<Func<T, bool>>
                (
                    Expression.Equal(
                        Expression.Property(
                            itemParameter,
                            typeof(T).GetPrimaryKey().Name
                        ),
                        Expression.Constant(id)
                    ),
                    new ParameterExpression[] { itemParameter }
                );

            var item = GetAll().Where(whereExpression).SingleOrDefault();

            if (item == null)
            {
                throw new Exception(string.Format("No {0} with primary key {1} found",
                    typeof(T).FullName, id));
            }

            return item;
        }

This issue is that the GetPrimaryKey extension method does not seem to work for LLBLGen entities.

Here’s the code for the extension:

public static class TypeExtensions
    {
        public static PropertyInfo GetPrimaryKey(this Type entityType)
        {
            foreach (PropertyInfo property in entityType.GetProperties())
            {
                if (property.IsPrimaryKey())
                {
                    if ((property.PropertyType != typeof(int)) && (property.PropertyType != typeof(Guid)))
                    {
                        throw new ApplicationException(string.Format("Primary key, '{0}', of type '{1}' is not int or guid",
                                                                     property.Name, entityType));
                    }
                    return property;
                }
            }

            throw new ApplicationException(string.Format("No primary key defined for type {0}", entityType.Name));
        }

        public static bool IsPrimaryKey(this PropertyInfo propertyInfo)
        {
            var columnAttribute = propertyInfo.GetAttributeOf<ColumnAttribute>();
            if (columnAttribute == null) return false;
            return columnAttribute.IsPrimaryKey;
        }

        public static TAttribute GetAttributeOf<TAttribute>(this PropertyInfo propertyInfo)
        {
            object[] attributes = propertyInfo.GetCustomAttributes(typeof(TAttribute), true);
            if (attributes.Length == 0)
            {
                return default(TAttribute);
            }
            return (TAttribute)attributes[0];
        }
    }

Is there a better way to accomplish this? I don’t like the reflection and I don’t think the GetCustomAttributes call will work for LLBLGen entities.

Any suggestions?

Thanks,

Rick

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 08-May-2010 10:05:35   

You can use PrimaryKeyFields property on the entity instance. It is a List of EntityField. Where do you have such extensions?

David Elizondo | LLBLGen Support Team
rboarman
User
Posts: 83
Joined: 01-Feb-2005
# Posted on: 14-May-2010 19:32:45   

I am not sure what you mean by "Where do you have such extensions?"

Rick

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 17-May-2010 02:46:03   

Ok. I think I misunderstand your code. I see now. But Isn't easier just using PrimaryKeyFields collection?


public static IEntityField GetPrimaryKey(this IEntity entity)
{
    return entity.PrimaryKeyFields[0];
}

public static IEntity GetById(this IEntity entity, object id)
{
    // get pk
    EntityField pkField = (EntityField) entity.GetPrimaryKey();

    // create filter
    IPredicateExpression filter = new PredicateExpression();
    filter.Add(pkField == id);

    // fetch
    IEntityCollection coll = entity.GetEntityFactory().CreateEntityCollection();
    coll.GetMulti(pkField == id);

    // return
    if (coll.Count > 0 )
    {
        return coll[0];
    }

    return entity.GetEntityFactory().Create();          
}
David Elizondo | LLBLGen Support Team
MTrinder
User
Posts: 1461
Joined: 08-Oct-2008
# Posted on: 17-May-2010 11:20:17   

See my reply to this thread which also has some thoughts on the Generic Get question.

http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=17868