忽视了实体框架6的所有属性,但有些 [英] Ignoring all properties but some in Entity Framework 6
问题描述
我要坚持使用实体框架。结果
我有一些较大的波苏斯,但我想存储一些只有属性的数据库中的一些数据。
我知道我可以用流利的API实现这个
使用忽略( )
方法。但有也不仅无视定义的属性的可能性,但所有的属性,但已定义的结果
所以,如果你有一个POCO是这样的:
公共类MyPoco
{
公众诠释标识{搞定;组; }
公共字符串名称{;组; }
。
。
。
公众诠释SomeSpecialId {搞定;组; }
}
和你只想要存储标识
和 SomeSpecialId
,你会怎么做:
保护覆盖无效OnModelCreating(DbModelBuilder建设者)
{
builder.Entity< MyPoco方式>()忽略(X => x.Name);
builder.Entity&所述; MyPoco方式>()忽略(X = GT; x.WhatEver);
。
。
。
//忽略一切,但Id和SomeSpecialId
base.OnModelCreating(制造商);
}
现在的问题是,如果你有扩展POCO但不希望坚持这些扩展属性也必须更改 OnModelCreating()
方法。那么,有没有做这样的事情的一种方式:
公共覆盖无效OnModelCreating(DbModelBuilder建设者)
{
builder.Entity&所述; MyPoco方式>()IgnoreAllBut(X => x.Id,x.SomeSpecialId);
base.OnModelCreating(制造商);
}
您可以写一个扩展方法这将这样做。因为你需要使用表达式树工作的代码并不简单。
下面是你IgnoreAllBut方式:
公共静态EntityTypeConfiguration< T> IgnoreAllBut< T>(这EntityTypeConfiguration< T> entityTypeConfiguration,
PARAMS表达式来; Func键< T,对象>> []属性),其中T:类
{
//摘自名表达式
VAR namesToKeep = properties.Select(A =>
{
VAR成员= a.Body为MemberExpression;
//如果该属性是一个值类型,将是一个额外的转换()
//这将摆脱它。
如果(成员== NULL)
{
无功转换= a.Body为UnaryExpression ;
如果(转换== NULL)抛出新的ArgumentException(无效的表达式);
会员= convert.Operand为MemberExpression;
}
如果(成员== NULL)抛出新的ArgumentException(无效的表达式);
回报(member.Member为的PropertyInfo).Name点;
});
//现在,我们遍历所有属性,但不包括我们要保持
的foreach(VAR属性的typeof的那些(T).GetProperties()式(P =方式>!namesToKeep.Contains(P .NAME)))
{
//这里是棘手的问题:我们需要建立一个表达式树
//传递给忽略()
//第一,参数
VAR参数= Expression.Parameter(typeof运算(T),E);
//然后属性访问
表达表达= Expression.Property(参数,属性);
//如果该属性是值类型,我们需要一个明确的转换()操作
如果(property.PropertyType.IsValueType)
{
表达式= Expression.Convert(表达式的typeof(对象));
}
//最后一步,一个拉姆达内组装一切
//可以传递到屏蔽()
变种结果= Expression.Lambda&所述; Func键&下; T,对象> >(表达式,参数);
entityTypeConfiguration.Ignore(结果);
}
返回entityTypeConfiguration;
}
I want to persist some data on a database using Entity Framework.
I have some bigger POCOs but I want to store some of the properties only.
I know that I can achieve this with the Fluent API
by using the Ignore()
method. But is there also the possibility of not only ignoring a defined property but all properties but the defined?
So if you have a POCO like this:
public class MyPoco
{
public int Id { get; set; }
public string Name { get; set; }
.
.
.
public int SomeSpecialId { get; set; }
}
And you only want to store the Id
and the SomeSpecialId
, you would do:
protected override void OnModelCreating(DbModelBuilder builder)
{
builder.Entity<MyPoco>().Ignore(x => x.Name);
builder.Entity<MyPoco>().Ignore(x => x.WhatEver);
.
.
.
// ignore everything but Id and SomeSpecialId
base.OnModelCreating(builder);
}
Problem now is that if you have to extend the POCO but don't want to persist those extended properties you also have to change the OnModelCreating()
method. So is there a way of doing something like:
public override void OnModelCreating(DbModelBuilder builder)
{
builder.Entity<MyPoco>().IgnoreAllBut(x => x.Id, x.SomeSpecialId);
base.OnModelCreating(builder);
}
You can write an extension method that will do that. The code is not simple because you need to work with expression trees.
Here is your IgnoreAllBut method:
public static EntityTypeConfiguration<T> IgnoreAllBut<T>(this EntityTypeConfiguration<T> entityTypeConfiguration,
params Expression<Func<T, object>>[] properties) where T : class
{
// Extract the names from the expressions
var namesToKeep = properties.Select(a =>
{
var member = a.Body as MemberExpression;
// If the property is a value type, there will be an extra "Convert()"
// This will get rid of it.
if (member == null)
{
var convert = a.Body as UnaryExpression;
if (convert == null) throw new ArgumentException("Invalid expression");
member = convert.Operand as MemberExpression;
}
if (member == null) throw new ArgumentException("Invalid expression");
return (member.Member as PropertyInfo).Name;
});
// Now we loop over all properties, excluding the ones we want to keep
foreach (var property in typeof(T).GetProperties().Where(p => !namesToKeep.Contains(p.Name)))
{
// Here is the tricky part: we need to build an expression tree
// to pass to Ignore()
// first, the parameter
var param = Expression.Parameter(typeof (T), "e");
// then the property access
Expression expression = Expression.Property(param, property);
// If the property is a value type, we need an explicit Convert() operation
if (property.PropertyType.IsValueType)
{
expression = Expression.Convert(expression, typeof (object));
}
// last step, assembling everything inside a lambda that
// can be passed to Ignore()
var result = Expression.Lambda<Func<T, object>>(expression, param);
entityTypeConfiguration.Ignore(result);
}
return entityTypeConfiguration;
}
这篇关于忽视了实体框架6的所有属性,但有些的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!