[英]Ignoring all properties but some in Entity Framework 6
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. 我有一些较大的POCO,但我只想存储一些属性。
I know that I can achieve this with the Fluent API
by using the Ignore()
method. 我知道可以通过使用
Ignore()
方法使用Fluent API
来实现此目的。 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: 因此,如果您有这样的POCO:
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: 而且您只想存储
Id
和SomeSpecialId
,您将执行以下操作:
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. 现在的问题是,如果您必须扩展POCO但又不想保留那些扩展的属性,则还必须更改
OnModelCreating()
方法。 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: 这是您的IgnoreAllBut方法:
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;
}
You can mark individual properties as NotMapped within the class itself. 您可以在类本身内将各个属性标记为NotMapped。
public class MyPoco
{
public int Id { get; set; }
[NotMapped]
public string Name { get; set; }
public int SomeSpecialId { get; set; }
}
Doesn't solve your issue of 'ignore everything but this' but might make it obvious what is and isn't included. 不能解决您的问题“忽略所有内容,但要做到这一点”,但可以使您清楚地知道其中包含和不包含的内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.