gpt4 book ai didi

entity-framework - Entity Framework : Tracking changes to independent associations

转载 作者:行者123 更新时间:2023-12-01 02:48:17 25 4
gpt4 key购买 nike

Entity Framework 可以轻松跟踪两个实体之间关系的更改。以下将返回所有添加和删除的关系的 ObjectStateEntry 实例:

ObjectStateManager.GetObjectStateEntries(
EntityState.Added | EntityState.Deleted)
.Where(e => e.IsRelationship);

出于审计目的,我想检索有关每个关联端的以下信息:
  • 导航属性名称(如果有)
  • 多样性

  • 对于添加的关联 ObjectStateEntry 实例包含关系中涉及的两个实体的 EntityKey 对象:
    var key0 = entry.CurrentValues[0] as EntityKey;
    var key1 = entry.CurrentValues[1] as EntityKey;

    它还引用表示当前关系的类型:
    var relationshipType = objectStateEntry.EntitySet.ElementType;

    我想要做的是将每个实体键(key0,key1)映射到关联的适当端(relationshipType.KeyMembers)。据我所知,唯一的方法是查看每个关联端的引用类型,并将其与实体键表示的实体类型进行匹配。但是,如果关联的两端引用相同的实体类型(想想具有引用另一名员工的经理 FK 的员工实体),这将不起作用。

    所以这里是我到目前为止获得导航属性名称和关系端多重性的辅助函数。有没有更好的方法来做同样的事情?
    public static string GetNavigationPropertyName(
    this ObjectStateEntry entry, EntityKey key)
    {
    var relationshipType = entry.EntitySet.ElementType;
    var entitySet = key.GetEntitySet(
    entry.ObjectStateManager.MetadataWorkspace);
    var property = entitySet.ElementType.NavigationProperties.Where(
    p => p.RelationshipType == relationshipType)
    .SingleOrDefault();

    if (property == null)
    {
    return null;
    }

    return property.Name;
    }

    public static RelationshipMultiplicity GetAssociationEndMultiplicity(
    this ObjectStateEntry entry, EntityKey key)
    {
    var relationshipType = entry.EntitySet.ElementType;

    var entitySet = key.GetEntitySet(
    entry.ObjectStateManager.MetadataWorkspace);

    foreach (EdmMember member in relationshipType.KeyMembers)
    {
    var refType = member.TypeUsage.EdmType as RefType;
    if (refType.ElementType == entitySet.ElementType)
    {
    var relEndMember = member as RelationshipEndMember;
    return relEndMember.RelationshipMultiplicity;
    }
    }
    throw new InvalidOperationException(
    "couldn't find association end");
    }

    欢迎任何建议/想法。

    谢谢,
    丹尼尔

    最佳答案

    与其查看实体键,不如从对象状态条目中提取关联端。我在 Daniel Simmons 的博客中看到了一个提示 http://blogs.msdn.com/b/dsimmons/archive/2008/01/17/ef-extension-methods-extravaganza-part-ii-relationship-entry-irelatedend.aspx .以下是我想出的一些扩展方法(UsableValues 也来自 Daniel 的博客):

    public static AssociationEndMember[] GetAssociationEnds(
    this ObjectStateEntry entry)
    {
    var fieldMetadata =
    entry.UsableValues().DataRecordInfo.FieldMetadata;

    return fieldMetadata.Select(
    m => m.FieldType as AssociationEndMember).ToArray();
    }

    public static AssociationEndMember GetOtherAssociationEnd(
    this ObjectStateEntry entry, AssociationEndMember end)
    {
    end.ValidateBelongsTo(entry);
    AssociationEndMember[] ends = entry.GetAssociationEnds();
    if (ends[0] == end)
    {
    return ends[1];
    }
    return ends[0];
    }

    public static EntityKey GetEndEntityKey(
    this ObjectStateEntry entry, AssociationEndMember end)
    {
    end.ValidateBelongsTo(entry);

    AssociationEndMember[] ends = entry.GetAssociationEnds();

    if (ends[0] == end)
    {
    return entry.UsableValues()[0] as EntityKey;
    }

    return entry.UsableValues()[1] as EntityKey;
    }

    public static NavigationProperty GetNavigationProperty(
    this ObjectStateEntry entry, AssociationEndMember end)
    {
    end.ValidateBelongsTo(entry);

    var otherEnd = entry.GetOtherAssociationEnd(end);
    var relationshipType = entry.EntitySet.ElementType;
    var key = entry.GetEndEntityKey(end);
    var entitySet = key.GetEntitySet(
    entry.ObjectStateManager.MetadataWorkspace);
    var property = entitySet.ElementType.NavigationProperties.Where(
    p => p.RelationshipType == relationshipType &&
    p.FromEndMember == end && p.ToEndMember == otherEnd)
    .SingleOrDefault();
    return property;
    }

    ValidateBelongsTo 扩展方法(UsableValue 是 Daniel 博客中的另一个扩展方法):
    static void ValidateBelongsTo(
    this AssociationEndMember end, ObjectStateEntry entry)
    {
    if (!entry.IsRelationship)
    {
    throw new ArgumentException("is not a relationship entry", "entry");
    }

    var fieldMetadata =
    entry.UsableValues().DataRecordInfo.FieldMetadata;
    if (fieldMetadata[0].FieldType as AssociationEndMember != end &&
    fieldMetadata[1].FieldType as AssociationEndMember != end)
    {
    throw new InvalidOperationException(string.Format(
    "association end {0} does not participate in the " +
    "relationship {1}", end, entry));
    }
    }

    关于entity-framework - Entity Framework : Tracking changes to independent associations,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6346026/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com