我正在使用Entity Framework 6,我需要更新实体的属性.
我有以下实体:
public class File { public Int32 Id { get; set; } public Byte Data { get; set; } public DateTime Updated { get; set; } public virtual Mime Mime { get; set; } } public class Mime { public Int32 Id { get; set; } public String Name { get; set; } public virtual ICollection<File> Files { get; set; } }
然后我使用了以下内容:
_repository.Update<File>(file,x => x.Data,x => x.Mime,x => x.Updated);
存储库方法如下:
public void Update<T>(T entity,params Expression<Func<T,Object>>[] properties) where T : class { _context.Set<T>().Attach(entity); foreach (var property in properties) { MemberExpression expression = property.Body is MemberExpression ? (MemberExpression)property.Body : (MemberExpression)(((UnaryExpression)property.Body) .Operand); _context.Entry<T>(entity) .Property(expression.Member.Name).IsModified = true; } }
这适用于Data和Updated属性,但不适用于Mime.我收到错误:
The property ‘Mime’ on type ‘File’ is not a primitive or complex property. The Property method can only be used with primitive or complex properties. Use the Reference or Collection method.
是否可以将其工作并将其集成到我的存储库方法中?
解决方法
是的,我认为可以做到.这里的问题是,我没有看到任何简单的方法来检查属性是表的一部分,还是导航属性.因此,很难称之为正确的行为.
如果您有兴趣,请查看EF6源代码,InternalEntityEntry.cs – >通过元数据进行大量属性验证的属性(..).
主要思想是基本扫描您的概念模型,并确定属性何时是导航属性(例如,如果属性导向另一个表),或者它是复杂/原始的.
据此,你称之为正确的功能.
var propertyName = expression.Member.Name; var propertyType = __get_property_type__(propertyName); if(propertyType==Property || propertyType==Complex) { _context.Entry<T>(entity) .Property(propertyName).IsModified = true; continue; } if(propertyType==Navigational){ // hm,do we need Attach it first?! // not sure.. have to test first. dynamic underlyingReference = entity.GetType() .GetProperty(propertyName) .GetValue(entity,null); _context.Entry(underlyingReference).State = EntityState.Modified; }
这里的问题是让__get_property_type__起作用.让你使用概念模型是Microsoft.Data.Edm.dll,但我认为这并不容易.
这是EF6如何检测我们是否处理引用属性的方式:
EdmMember member; EdmEntityType.Members.TryGetValue(propertyName,false,out member); var asNavProperty = member as NavigationProperty; // if asNavProperty!=null,we have navigation property.