tags:

views:

26

answers:

3

I have generic repository. There is a method Save() to persist entity in db. I want to check primary key through Table.GetPropertyValue("ID", entity) - how i should implement it?

private Table<T> Table
{
    get { return db.GetTable<T>(); }
}

public void Save(T entity)
{
    if (Table.GetPropertyValue("ID", entity) == 0)
    {
         Add(entity);
    }
    else if (Table.GetOriginalEntityState(entity) == null)
    {
         Table.Attach(entity);
         Table.Context.Refresh(RefreshMode.KeepCurrentValues, entity);
    }
    db.SubmitChanges();
}
+3  A: 

You can use dynamic in C# 4:

if (((dynamic)entity).ID == 0)
    ....
Kirk Woll
nice! but I need in NET 3.5
eldar
@eldar, in that case, use either klausbyskov's or Rob's solution. :)
Kirk Woll
+2  A: 

you could use reflection, but for this use case i'd recommend creating an interface:

public interface IHasId
{
    public int ID{get;}
}

make all the relevant tables implement this interface (in the partial class definition), then you can try and cast entity into an IHasId

Rob Fonseca-Ensor
+1, this is the best solution. `dynamic` and reflection are not statically type-safe -- this is.
Kirk Woll
personally i liked your dynamic solution more - shiny :)
Rob Fonseca-Ensor
@Rob, ha ha, ah well, nice to have too *many* options rather than too few. ;)
Kirk Woll
A: 

Say I have a class B defined as follows:

public class B
{
    public int Id { get; set; }
}

Then you could get the value of the id like this:

var b = new B();
b.Id = 60;
int id = GetId(b);

with the GetId method defined as follows:

    public static int GetId(object o)
    {
        var idProperty = o.GetType().GetProperties().FirstOrDefault(p => p.Name == "Id");

        if (idProperty == null)
            throw new ArgumentException("object does not have an Id property", "o");

        if (idProperty.PropertyType.FullName != typeof(Int32).FullName)
            throw new ArgumentException("object has an Id property, but it is not of type Int32", "o");

        return (int)idProperty.GetValue(o, new object[] { });
    }

A more generic solution would be to make a method like this:

    public static T GetProperty<T>(object o, string propertyName)
    {
        var theProperty = o.GetType().GetProperties().FirstOrDefault(p => p.Name == propertyName);

        if (theProperty == null)
            throw new ArgumentException("object does not have an " +  propertyName + " property", "o");

        if (theProperty.PropertyType.FullName != typeof(T).FullName)
            throw new ArgumentException("object has an Id property, but it is not of type " + typeof(T).FullName, "o");

        return (T)theProperty.GetValue(o, new object[] { });
    }

which would be called like so:

var b = new B();
b.Id = 60;
int id = GetProperty<int>(b, "Id");
klausbyskov
I need more general solution Table.GetPropertyValue("Some_Property", entity). May be through extension method
eldar
@eldar, I have updated my answer.
klausbyskov
it works! Thanks!
eldar
@eldar, happy to help.
klausbyskov
there's always `o.GetType().GetProperty(propertyName);` too :P
Rob Fonseca-Ensor