好了,所以......
的主要问题是,我有这个类:处理object
键时
public class UniqueEntity {
[key]
public object Key { get; set; }
}
但EntityFramework
弄乱表的创建。我的想法是,关键可以是任何类型,由子类指定。
我开始使用泛型:
public class UniqueEntity<T> where T : IComparable, IComparable<T>
{
[Key]
public T Key { get; set; }
}
这在一开始效果不错,但导致了严重的设计问题,后来创建我的通用存储库(库的定义是一样IRepository<T,E>
,当IRepository<E>
就足够了的时候。
所以,EntityFramework
使用与Key
属性注释,以获得实体的主要类型物业的PropertyInfo
值。如果只有我可以将该类型更改为用户希望它(在运行时),并避免使用泛型,它会很棒。
事实证明,你不能删除属性,或带有自定义属性更改其类型buuuuuut ..实际上,你可以创建一个新的虚拟财产,并从原来的Key
属性中删除属性!
为此,我们需要一个CustomReflectionContext
(System.Reflection。上下文):
public class Modifier : CustomReflectionContext
{
private string propName;
private object propValue;
public Modifier(string propName, object propValue)
{
this.propName = propName;
this.propValue = propValue;
}
protected override IEnumerable<PropertyInfo> AddProperties(Type type)
{
Type newType = MapType(propValue.GetType().GetTypeInfo());
return CreateProperty(newType, propName, o => propValue, (o, v) => propValue = v,
new Attribute[] { new KeyAttribute() }, new Attribute[] { }, new Attribute[] { });
}
protected override IEnumerable<object> GetCustomAttributes(MemberInfo member, IEnumerable<object> declaredAttributes)
{
return new Attribute[] { };
}
}
有了这个小类的帮助下,我们能够创建自己的自定义类型给予EntityFramework
,并使用具有现在[Key]
标注一个新的属性:
var context = new Modifier("NewKey", 0);
var uniqueEntityType = context.MapType(typeof(UniqueEntity).GetTypeInfo());
var keyType = uniqueEntityType.GetProperty("Key").PropertyType;
var keyAttrs = uniqueEntityType.GetProperty("Key").GetCustomAttributes();
var newKeyType = uniqueEntityType.GetProperty("NewKey").PropertyType;
var newKeyAttrs = uniqueEntityType.GetProperty("NewKey").GetCustomAttributes();
Console.WriteLine("Key Property. Type: {0}, Attribute: {1}", keyType, keyAttrs.FirstOrDefault());
Console.WriteLine("NewKey Property. Type: {0}, Attribute: {1}", newKeyType, newKeyAttrs.FirstOrDefault());
Console.ReadLine();

备案。我想这样做,因为'Key'将被标注一个属性。外部框架将识别该属性并从'PropertyType'中获取它的类型。如果返回'System.Int32'而不是'System.Object',将会很棒。 – 2014-11-24 05:00:08
有趣的问题。我不相信你可以在运行时做到这一点。但作为一个对象,你可以在其中存储任何东西,然后做运行时投射。 – 2014-11-24 05:04:43
不可能是你想要的,但是你可以继承这个类并创建新的属性来转换该属性,而你只使用新的属性。 – 2014-11-24 05:05:30