【问题标题】:Entity Framework - Code First - Ignore all properties except those specified实体框架 - 代码优先 - 忽略除指定属性之外的所有属性
【发布时间】:2015-08-05 04:50:45
【问题描述】:

我正在处理一些具有大量属性的大型类,我不想忽略所有我不想保存到数据库中的属性。相反,是否有忽略所有属性并仅指定我想要的属性?

所以不是这个

protected override void OnModelCreating(DbModelBuilder mb)
{
    // code to ignore properties i don't want one at a time, i.e.
    mb.Entity<Person>().Ignore(i => i.Name);
    mb.Entity<Person>().Ignore(i => i.Birthday);
}

我会的

protected override void OnModelCreating(DbModelBuilder mb)
{
    // code to ignore all properties
    // code to include only properties I want
}

【问题讨论】:

  • 您能否提供一些关于为什么这是一个问题的背景信息?换句话说,您如何保存使您想以这种方式忽略属性的数据?
  • 仅在视图模型中忽略属性可能是一种可能的解决方法。在模型中包含必要的属性并在视图模型中具有所有属性(具有忽略的属性)
  • @BrendanGreen 我正在使用 ebay SDK。有很多类,它们有很多属性,没有一个指定键。我只想将少量数据保存到数据库中。只能够选择我想要的而不是忽略我不想要的一切会节省很多时间。
  • 这是否意味着您刚刚在 SDK 之后直接对数据库进行了建模?也许我在这里遗漏了一些东西,但是如果您想忽略所有这些属性,那么只需将它们从您的数据模型中删除即可。或者,如前所述(假设这是一个 Web 应用程序),使用视图模型在控制器和视图之间传递数据,您根本不必处理不需要的字段。
  • @BrendanGreen 是的,我已经根据 SDK 对数据库进行了建模。抱歉,我是 EF 新手,你说从我的数据模型中删除我不想要的那些是什么意思?

标签: c# entity-framework code-first ef-fluent-api


【解决方案1】:

您可以使用 reflection 为所有属性调用 Ignore 方法,但您需要的属性除外。可以通过创建这样的扩展方法来实现:

public static class EntityTypeConfigurationExtentions
{
    public static EntityTypeConfiguration<TEntityType> IgnoreAllExcept<TEntityType>
       (this EntityTypeConfiguration<TEntityType> t, params string[] except)
        where TEntityType:class
    {
        var type = typeof(TEntityType);
        var properties = type.GetProperties();
        var dontIgnore = except ?? new string[0];
        //Here you can add more constraints on the class properties
        var toIgnore = properties.Where(x => !except.Contains(x.Name) && 
                                             x.SetMethod != null).ToList();
        foreach (var name in toIgnore)
        {
            var selector = GetIgnoreExpression<TEntityType>(name);
            MethodInfo genericMethod = GetIgnoreMethod<TEntityType>(name.PropertyType);
            genericMethod.Invoke(t, new object[] { selector });
        }
        return t;
    }
    private static MethodInfo GetIgnoreMethod<TEntityType>(Type propType)
    {
        var t = typeof(EntityTypeConfiguration<>);
        t = t.MakeGenericType(typeof(TEntityType));
        MethodInfo method = t.GetMethod("Ignore");
        MethodInfo genericMethod = method.MakeGenericMethod(propType);
        return genericMethod;
    }
    //This method creates the 'x=>x.PropertyName' expression for Ignore method
    private static Expression GetIgnoreExpression<TEntityType>(PropertyInfo prop)
    {
        ParameterExpression arg = Expression.Parameter(typeof(TEntityType), "x");
        MemberExpression property = Expression.Property(arg, prop.Name);
        var exp = Expression.Lambda(property, new ParameterExpression[] { arg });
        return exp;
    }
}

首先我们提取所有具有setter的类的属性(如果你有更多的约束,你最多提供它们)并且不属于异常列表,然后我们调用Ignore EntityTypeConfiguration&lt;TEntityType&gt; 类的每个属性的方法,以便忽略该属性。

调用Ignore方法需要获取泛型类类型,然后找到该类的Ignore方法,然后提供Ignore方法的泛型类型,最后通过适当的论据。

Ignore 方法的参数是通过创建一个从 TEntityType 类中选择所需属性的 lambda 表达式来获得的。

定义完这个扩展类后,你可以像这样调用IgnoreAllExcept

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
       modelBuilder.Entity<TestClass>().IgnoreAllExcept("Id", "Name");
}

您还可以通过将except 参数更改为选择类属性的表达式来改进此方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多