ASP .NET 5 MVC Core application.
Following method is used to find entity by key:
class MyStudents: Students { }
public TEntity FindNormalized<TEntity>(params object[] keyValues)
where TEntity : class
{
return Find<TEntity>(keyValues);
}
void FindNormalized<TEntity>(TEntity entity, params object[] keyValues)
where TEntity : class
{
var res = FindNormalized<TEntity>(keyValues);
if (res == null)
throw new KeyNotFoundException(entity.GetType().Name + " entity key not found " + keyValues[0]);
CopyPropertiesTo(res, entity);
}
static void CopyPropertiesTo<T, TU>(T source, TU dest)
{ // https://stackoverflow.com/questions/3445784/copy-the-property-values-to-another-object-with-c-sharp
var sourceProps = typeof(T).GetProperties().Where(x => x.CanRead).ToList();
var destProps = typeof(TU).GetProperties()
.Where(x => x.CanWrite)
.ToList();
foreach (var sourceProp in sourceProps)
if (destProps.Any(x => x.Name == sourceProp.Name))
{
var p = destProps.First(x => x.Name == sourceProp.Name);
p.SetValue(dest, sourceProp.GetValue(source, null), null);
}
}
Using it with subclass
FindNormalized<MyStudents>(1);
throws exception
Cannot create a DbSet for 'MyStudents' because this type is not included in the model for the context.
FindNormalized<Students>(1);
works.
How to fix this so that it can used with subclass type also ?
For getting table attribute from subclass code from Dynamic Linq works:
string GetTableAttrib(Type t)
{
foreach (Type t2 in SelfAndBaseClasses(t))
{
IEntityType entityType = Model.FindEntityType(t2);
if (entityType == null)
continue;
return entityType.GetTableName();
}
throw new ApplicationException(t.FullName + " no table attribute");
}
/// <summary>
/// Enumerate inheritance chain - copied from DynamicLinq
/// </summary>
static IEnumerable<Type> SelfAndBaseClasses(Type type)
{
while (type != null)
{
yield return type;
type = type.BaseType;
}
}
Maybe this can used to implement Find also. Unfortunately Find throws exception. Is it reasonable to wrap Find using try/catch or is there better way ?