POCO 的代理是从(继承)POCO派生的动态创建的类。EntityObject
只要 POCO 满足要求,它就会添加之前在 中找到的功能,即延迟加载和更改跟踪。正如问题所暗示的那样,POCO 或其代理不包含EntityObject
,而是代理包含EntityObject
. 您不能(AFAIK)将 ModelBuilder 与 EntityObject 衍生物一起使用,并且您不能从 POCO 或代理获取基础 EntityObject,因为没有这样的实体。
我不知道ObjectContext
您现有的序列化和审计代码使用了哪些功能,但是您可以通过将 a 转换为 a并访问属性来ObjectContext
从 a获取。DbContext
DbContext
IObjectContextAdapter
IObjectContextAdapter.ObjectContext
编辑:
1. 访问 ObjectStateEntry 中可用的 Save Changes 中的已修改属性并将它们保存到 Audit 中,并使用旧值和新值
您可以通过使用 POCO 来实现这一点DbContext.ChangeTracker
。首先,您调用DbContext.ChangeTracker.DetectChanges
以检测更改(如果您使用代理,这不是必需的,但不会受到伤害),然后您使用DbCotnext.Entries.Where(e => e.State != EntityState.Unchanged && e.State != EntityState.Detached)
获取DbEntityEntry
更改实体的列表以进行审计。每个DbEntityEntry
都有OriginalValues
并且CurrentValues
实际的 Entity 在 property 中Entity
。
您还可以访问ObjectStateEntry
,见下文。
2. 大多数时候,我们只需要检查 Navigation Property 上的 Any 条件,例如:
User.EmailAddresses.CreateSourceQuery().Any( x=> x.EmailAddress == givenAddress);
您可以通过利用前面描述的 IObjectContextAdapter 将 CreateSourceQuery() 与 DbContext 一起使用。当您拥有 ObjectContext 时,您可以像这样访问相关端的源查询:
public static class DbContextUtils
{
public static ObjectQuery<TMember> CreateSourceQuery<TEntity, TMember>(this IObjectContextAdapter adapter, TEntity entity, Expression<Func<TEntity, ICollection<TMember>>> memberSelector) where TMember : class
{
var objectStateManager = adapter.ObjectContext.ObjectStateManager;
var objectStateEntry = objectStateManager.GetObjectStateEntry(entity);
var relationshipManager = objectStateManager.GetRelationshipManager(entity);
var entityType = (EntityType)objectStateEntry.EntitySet.ElementType;
var navigationProperty = entityType.NavigationProperties[(memberSelector.Body as MemberExpression).Member.Name];
var relatedEnd = relationshipManager.GetRelatedEnd(navigationProperty.RelationshipType.FullName, navigationProperty.ToEndMember.Name);
return ((EntityCollection<TMember>)relatedEnd).CreateSourceQuery();
}
}
此方法不使用动态代码并且是强类型的,因为它使用表达式。你像这样使用它:
myDbContext.CreateSourceQuery(invoice, i => i.details);