我的数据库设计师没有使用标准" Id"对于我的数据库中的主键字段,所以我需要为我正在编写的通用存储库找到以下内容。
我正在尝试使用如下所示的Generated脚手架代码并创建一个通用存储库:
public void InsertOrUpdate(Entity entity)
{
if (entity.EntityID == default(int))
{
// New entity
_context.Entry(entity).State = System.Data.Entity.EntityState.Added;
}
else
{
// Existing entity (TODO: Wont add the whole graph of things)
_context.Entry(entity).State = System.Data.Entity.EntityState.Modified;
}
}
我通过执行以下操作找到了主键名称:
public string FindPrimaryKey()
{
var objectSet = ((IObjectContextAdapter)_context).ObjectContext.CreateObjectSet<Entity>();
string keyName = objectSet.EntitySet.ElementType.KeyMembers.Select(k => k.Name).FirstOrDefault();
return keyName;
}
我接近使用以下代码获取主键CLR类型:
public string FindPrimaryKeyType()
{
var objectSet = ((IObjectContextAdapter)_context).ObjectContext.CreateObjectSet<Entity>();
string keyType = objectSet.EntitySet.ElementType.KeyMembers.Select(k => k.TypeUsage.EdmType.FullName).FirstOrDefault();
var keyType2 = from m in objectSet.EntitySet.ElementType.KeyMembers
select m.TypeUsage.EdmType;
return "";
}
我在调试上面的代码时可以看到ClrType,但我还没有弄清楚如何从ClrType中获取Type:
所以,请帮我弄清楚如何获取ClrType,或者更好地了解如何做到这一点。
答案 0 :(得分:3)
您已经获得了表示属性名称的键名,只需使用反射来获取属性类型。
var objectSet = ((IObjectContextAdapter)_context).ObjectContext.CreateObjectSet<Entity>();
var keyNames = objectSet.EntitySet.ElementType.KeyMembers.Select(k => k.Name).ToArray();
获取clr类型。
var types = keyNames.Select(keyName => typeof(Entity).GetProperty(keyName).PropertyType).ToArray();
获取默认值。
var defaultValues = types.Select(type => type.IsValueType ? Activator.CreateInstance(type) : null).ToArray();
在课堂上包装所有内容
public class EntityHelper<Entity> where Entity :class
{
private DbContext _context;
public EntityHelper(DbContext context)
{
_context = context;
}
public string[] FindPrimaryKeyNames()
{
var objectSet = ((IObjectContextAdapter)_context).ObjectContext.CreateObjectSet<Entity>();
var keyNames = objectSet.EntitySet.ElementType.KeyMembers.Select(k => k.Name).ToArray();
return keyNames;
}
public Type[] FindPrimaryKeyTypes()
{
var keyNames = FindPrimaryKeyNames();
var types = keyNames.Select(keyName => typeof(Entity).GetProperty(keyName).PropertyType).ToArray();
return types;
}
public object[] FindPrimaryKeyDefaultValues()
{
var types = FindPrimaryKeyTypes();
var defaultValues = types.Select(type => type.IsValueType ? Activator.CreateInstance(type) : null).ToArray();
return defaultValues;
}
}
答案 1 :(得分:1)
我不知道从模型元数据公开的EdmType
映射到本地.Net Type
的任何直接方法。 Yuliam提供了一种混合方法,可以切换到.Net反射来解析类型。
如果您想坚持使用Entity Framework元数据,您可以自己进行映射,如下面的代码示例所示。这是我所处的代码,其灵感来自以下SO问题:Is there a mapper to/from EDM/OData types to CLR types?
private static Type GetTypedEdmValue(EdmType type)
{
switch (type.FullName)
{
case "Edm.String": return typeof(string);
case "Edm.Byte": return typeof(byte);
case "Edm.SByte": return typeof(sbyte);
case "Edm.Int16": return typeof(short);
case "Edm.Int32": return typeof(int);
case "Edm.Int64": return typeof(long);
case "Edm.Double": return typeof(double);
case "Edm.Single": return typeof(float);
case "Edm.Boolean": return typeof(bool);
case "Edm.Decimal": return typeof(decimal);
case "Edm.DateTime": return typeof (DateTime);
case "Edm.Guid": return typeof (Guid);
default: throw new NotSupportedException("Not supported type " + type);
}
}
要获取类型的默认值,您可以使用以下内容。同样,我所处的代码最初来自以下SO问题:Default value of a type at Runtime
object GetDefaultValue(Type t)
{
if (t.IsValueType)
return Activator.CreateInstance(t);
return null;
}
然后使用如下:
var objectContext = (context as IObjectContextAdapter).ObjectContext;
var entitySet = objectContext.CreateObjectSet<YOUR_ENTITY>().EntitySet;
var keys = entitySet.ElementType.KeyMembers.Select(k =>
{
var type = GetTypedEdmValue(k.TypeUsage.EdmType);
return new
{
KeyName = k.Name,
KeyType = type,
KeyDefaultValue = GetDefaultValue(type)
};
}).ToList();
为了示例的目的,这只是为了返回一个包含键名,类型和默认值的匿名类型列表。