I am trying to export Asp.Net Identity classes in the OData metadata. Now the the IdentityUserLogin
class contains three primary keys which are not marked with [Key]
attribute. When the metadata is generated, the key definition is missing in the output
<EntityType Name="IdentityUserLogin">
<Property Name="LoginProvider" Type="Edm.String"/>
<Property Name="ProviderKey" Type="Edm.String"/>
<Property Name="UserId" Type="Edm.String"/>
</EntityType>
Normally, to fix this all I need to do is add the keys manully using HasKey
method like so
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<IdentityUserLogin>("Logins").EntityType
.HasKey(l => new { l.LoginProvider, l.ProviderKey, l.UserId });
var EDM = builder.GetEdmModel();
config.Routes.MapODataServiceRoute("odata", "api", EDM,
new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
while the above generates the key definition for the entity, it also creates duplicate columns
<EntityType Name="IdentityUserLogin">
<Key>
<PropertyRef Name="LoginProvider"/>
<PropertyRef Name="ProviderKey"/>
<PropertyRef Name="UserId"/>
</Key>
<Property Name="LoginProvider" Type="Edm.String" Nullable="false"/>
<Property Name="ProviderKey" Type="Edm.String" Nullable="false"/>
<Property Name="UserId" Type="Edm.String" Nullable="false"/>
<Property Name="LoginProvider" Type="Edm.String"/>
<Property Name="ProviderKey" Type="Edm.String"/>
<Property Name="UserId" Type="Edm.String"/>
</EntityType>
Am I doing something wrong here ? Note that this also happens with IdentityUserRole
class.
There is a way to avoid the bug mentioned here and here, if one derives the identity types - e.g. in order to have different type of keys. Since I derive all identity types and the relevant properties are virtual, I am able to override the key properties an set the [Key] attribute. Thus I don't need to explicitly define the keys and thus can avoid the duplicate-property-bug.
public class UserLogin : MultitenantIdentityUserLogin<Guid, Guid>
{
[Key]
public override Guid TenantId
{
get { return base.TenantId; }
set { base.TenantId = value; }
}
[Key]
public override string LoginProvider
{
get { return base.LoginProvider; }
set { base.LoginProvider = value; }
}
[Key]
public override string ProviderKey
{
get { return base.ProviderKey; }
set { base.ProviderKey = value; }
}
[Key]
public override Guid UserId
{
get { return base.UserId; }
set { base.UserId = value; }
}
}
public class UserRole : IdentityUserRole<Guid>
{
[Key]
public override Guid UserId
{
get { return base.UserId; }
set { base.UserId = value; }
}
[Key]
public override Guid RoleId
{
get { return base.RoleId; }
set { base.RoleId = value; }
}
}
public class UserClaim : IdentityUserClaim<Guid>
{
[Key]
public override int Id
{
get { return base.Id; }
set { base.Id = value; }
}
}
Regards, Kasimier Buchcik