2015-06-26 52 views
1

我想使用實體框架在數據庫上保存一些數據。
我有一些更大的POCO,但我只想存儲一些屬性。忽略實體框架中的所有屬性6

我知道我可以通過使用Ignore()方法與Fluent API達到此目的。但是,是否也有可能不僅忽略定義的屬性,而且還定義了所有屬性?
所以,如果你有一個POCO這樣的:

public class MyPoco 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    . 
    . 
    . 
    public int SomeSpecialId { get; set; } 
} 

而你只想要存儲IdSomeSpecialId,你會怎麼做:

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()方法。那麼有沒有辦法做這樣的事情:

public override void OnModelCreating(DbModelBuilder builder) 
{ 
    builder.Entity<MyPoco>().IgnoreAllBut(x => x.Id, x.SomeSpecialId); 
    base.OnModelCreating(builder); 
} 
+0

也許使用自定義Coventions? http://stackoverflow.com/questions/22038690/entity-framework-ignore-property-by-conventions – ErikEJ

+0

@ErikEJ我沒有基類,我不能有一些原因。 –

回答

3

你可以寫一個擴展方法來做到這一點。代碼並不簡單,因爲您需要使用表達式樹。

這裏是你的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; 
} 
1

你可以標記單個屬性爲NotMapped類本身。

public class MyPoco 
{ 
    public int Id { get; set; } 

    [NotMapped] 
    public string Name { get; set; } 

    public int SomeSpecialId { get; set; } 
} 

沒有解決您'忽略一切,但是這個'的問題,但可能會明確什麼是和不包括在內。

+0

好吧,這不容易解釋。我不能這樣做,因爲這會將該屬性設置爲全局忽略。 POCO在EF持久性的另一個項目(DLL)內。因此,POCO可能會在項目中存儲兩個屬性,但在另一個項目中存在不同的屬性。 –