0

Is there a way to write a base entity, where the primary key's type is not specified using generics?

For instance, I have been doing this so far:

public class BaseUniqueEntity<T> where T : IComparable, IComparable<T> {
    [Key]
    public T Key{ get; set; }
}

This was good at the time, but now is giving me design problems. For example, when coding a generic repository I am obligued to specify two type constraints:

public interface IRepository<K, E>
    where K : IComparable, IComparable<K>
    where E : BaseUniqueEntity<K>

I would only want to specify the entity's type E, but I need the K type for specifying the where E : BaseUniqueEntity<K> constraint.

I can't make Key of type object, because it messes up when creating my tables for me.

So I was think of removing generics from BaseUniqueEntity. Is there a way to accomplish this? I'm out of ideas and I'm pretty new to Entity Framework.

2
  • You can - make it something that's fully defined: int, Guid, string, whatever. But then all your entities will have to have primary key typed as that. Commented Nov 24, 2014 at 2:39
  • I would really love that child classes could decide what type their key would be Commented Nov 24, 2014 at 4:39

2 Answers 2

1

Is there a way to write a base entity, where the primary key's type is not specified using generics?

Why must you write a base entity? Ostensibly, all you're doing is trying to enforce a key on each entity, and that might not even make sense for the type (composite keys might make more sense, which EF supports). Regardless, the Key attribute is required for an entity anyway, so what is being enforced exactly?

There's no rule saying that everything must inherit from a base class. My advice: if you don't think it makes sense for callers to always define the key type, then just write classes that define their own keys, with types that make sense for the them.

Sign up to request clarification or add additional context in comments.

3 Comments

But If there's no abstract or base class, and therefore no base Key property, how can I build a generic repository? How would I get the entity's key if its known only by the implementation entity?
@MatiCicero Reflection. Something like this should work: var keyProperty = entity.GetProperties().Where(p => Attribute.IsDefined(p, typeof(KeyAttribute)));
@MatiCicero Why do you need to know the Key property to build a repo? Have you seen the DbSet.Find method? Have you exposed the IQueryable<T>? This is not a case of Inheritance. Does it satisfy Listkov?
0

How about keep the generic IRepository interface and define another interface as a shortcut for default key (int, guid, etc) Something like this:

public interface IRepository<K, E>
    where K : IComparable, IComparable<K>
    where E : BaseUniqueEntity<K>
{
}

public interface IRepository<E> : IRepository<int, E>
    where E : BaseUniqueEntity<int>
{
}

When defining concrete Repository:

public class UserRepository<User>
{
}

1 Comment

This approach came to my mind too, but I don't like the idea of creating new IRepisotry for each possible type of Key

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.