使用OData ODataModelBuilder注册IdentityUser和/或IdentityRole子类

本文关键字:IdentityRole 子类 IdentityUser OData ODataModelBuilder 注册 使用 | 更新日期: 2023-09-27 18:19:58

我在将Identity Framework的IdentityUser和IdentityRole与我的应用程序集成时遇到了一些问题。以下是我对IdentityRole所做的工作。

我在我的应用程序中对IdentityRole进行了子类化,如下所示:

public partial class ActionRole : IdentityRole, IObjectState, ICanBeDisabledEntity, IAuditableEntity 
{
    ...
}

我正试图使用ODataModelBuilder:将"ActionRole"注册为实体集

public static Microsoft.Data.Edm.IEdmModel GetModel()
    {
        ODataModelBuilder builder = new ODataConventionModelBuilder();
        ...
        builder.EntitySet<ActionRole>(typeof(ActionRole).Name);
        ...
        return builder.GetEdmModel();
    }

但是,当应用程序在:上运行ODataConventionModelBuilder.GetEdmModel

return builder.GetEdmModel(); 

方法调用返回以下异常:

System.InvalidOperationException: Sequence contains more than one element

我在System.Web.Http.OData库中查找了一下,发现这是异常的来源:

internal void RemoveBaseTypeProperties(IEntityTypeConfiguration derivedEntity, IEntityTypeConfiguration baseEntity)
    {
        IEnumerable<IEntityTypeConfiguration> typesToLift = new[] { derivedEntity }.Concat(this.DerivedTypes(derivedEntity));
        foreach (PropertyConfiguration property in baseEntity.Properties.Concat(baseEntity.DerivedProperties()))
        {
            foreach (IEntityTypeConfiguration entity in typesToLift)
            {
                PropertyConfiguration derivedPropertyToRemove = entity.Properties.Where(p => p.Name == property.Name).SingleOrDefault();
                if (derivedPropertyToRemove != null)
                {
                    entity.RemoveProperty(derivedPropertyToRemove.PropertyInfo);
                }
            }
        }
    }

PropertyConfiguration derivedPropertyToRemove = entity.Properties.Where(p => p.Name == property.Name).SingleOrDefault();指向我的ActionRole实体,它有多个同名属性,但我检查了它,似乎没有重复。

这是我的ActionRole类:

public class ActionRole : IdentityRole, IObjectState, ICanBeDisabledEntity, IAuditableEntity 
{
    private const String CacheKey = "somekey";
    [DisplayName("Rol")]
    [InversePropertyAttribute("ActionRole")]
    public virtual ICollection<Role> Role { get; set; }
    public static string GetCacheKey(String roleName)
    {
        return CacheKey + roleName;
    }
    public ObjectState ObjectState
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            throw new NotImplementedException();
        }
    }
    public bool IsDisabled
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            throw new NotImplementedException();
        }
    }
    public string CreateUser
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            throw new NotImplementedException();
        }
    }
    public DateTime CreateTime
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            throw new NotImplementedException();
        }
    }
    public string UpdateUser
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            throw new NotImplementedException();
        }
    }
    public DateTime UpdateTime
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            throw new NotImplementedException();
        }
    }
}
}

我很想了解为什么会发生这种情况,或者如何解决。谢谢

使用OData ODataModelBuilder注册IdentityUser和/或IdentityRole子类

事实证明,.NET Identity使用字符串id作为其所有模型的默认标识符。因为我在模型中使用了一个int Id字段,所以这句话导致了多次匹配:

PropertyConfiguration derivedPropertyToRemove = entity.Properties.Where(p => p.Name == property.Name).SingleOrDefault();

即具有相同名称但不同类型的两个属性。

我正在将所有模型切换为整数键,如下所示:http://typecastexception.com/post/2014/07/13/ASPNET-Identity-20-Extending-Identity-Models-and-Using-Integer-Keys-Instead-of-Strings.aspx

我不太清楚.NET身份团队为什么决定走这条路,但这代表着对我的遗留应用程序的重大更改,我没有资源来完成这些更改。

那个博客一直是我的救命稻草。不错的东西。