问题描述
我想使用实体框架将一些数据保存在数据库中.
我有一些更大的 POCO,但我只想存储一些属性.
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.
我知道我可以通过 Fluent API
使用 Ignore()
方法来实现这一点.但是是否也有可能不仅忽略已定义的属性,还忽略除已定义的所有属性吗?
因此,如果您有这样的 POCO:
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; }
}
而你只想存储 Id
和 SomeSpecialId
,你会这样做:
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);
}
现在的问题是,如果您必须扩展 POCO 但不想保留这些扩展属性,您还必须更改 OnModelCreating()
方法.那么有没有办法做这样的事情:
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.
这是您的 IgnoreAllBut 方法:
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 中的所有属性,但部分属性除外的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!