Drop foreign key for UserClaim or change model Code first approach - entity-framework

I created a linked table between Users and Tenants called UserTenants.
Now I want to drop the foreign key column: UserId. The problem is that I can't find the model for UserClaim which I can edit. I've tried to create a new one like this:
public class UserClaim : CreationAuditedEntity<long>{
[Key]
public int Id { get; set; }
public const int MaxClaimTypeLength = 256;
public virtual int? TenantId { get; set; }
public virtual long UserId { get; set; }
public virtual User User { get; set; }
[StringLength(256)]
public virtual string ClaimType { get; set; }
public virtual string ClaimValue { get; set; }
public UserClaim() {
}
public UserClaim(AbpUserBase user, Claim claim)
{
TenantId = user.TenantId;
UserId = user.Id;
ClaimType = claim.Type;
ClaimValue = claim.Value;
}
}
But the Error I'm getting is:
System.InvalidOperationException: Cannot use table 'UserClaims' for entity type 'UserClaim' since it is being used for entity type 'UserClaim' and potentially other entity types, but there is no linking relationship. Add a foreign key to 'UserClaim' on the primary key properties and pointing to the primary key on another entity type mapped to 'UserClaims'.

Related

Entity framework code first cant create primary and foreign key relationship

I am trying to create a relationship between two tables but keep getting the following error:
The ForeignKeyAttribute on property 'CallLogId' on type
'Ylp.Web.ParkingApi.DataLayer.Entities.ApiCallLogDetailEntity' is not
valid. The navigation property 'ApiCallLog' was not found on the
dependent type
'Ylp.Web.ParkingApi.DataLayer.Entities.ApiCallLogDetailEntity'. The
Name value should be a valid navigation property name.
DbContextMapping:
modelBuilder.Entity<ApiCallLogDetailEntity>()
.HasRequired<ApiCallLogEntity>(p => p.ApiCallLog);
Primary table:
[Table("ApiCallLog")]
public class ApiCallLogEntity
{
[Key, Column(Order = 0)]
public string CallLogId { get; set; }
[Key, Column(Order = 1)]
public string UserId { get; set; }
[Required]
public string CallFilterId { get; set; }
[Required]
public DateTime LastUpdated { get; set; }
[Required]
public int Count { get; set; }
public virtual ICollection<ApiCallLogDetailEntity> Details { get; set; }
}
foreign table:
[Table("ApiCallLogDetail")]
public class ApiCallLogDetailEntity
{
[ForeignKey("ApiCallLog")]
public string CallLogId { get; set; }
[Required]
public string PrametersHashCode { get; set; }
[Required]
public DateTime LastUpdated { get; set; }
public ApiCallLogEntity ApiCallLog { get;}
}
The foreign key must refer to the whole primary key of the parent table. In your parent table you have a composite primary key which includes CallLogId and UserId. The message is confusing, but this can be part of the error. Is it really necessary to include the UserId in the PK?
Another error is that you have not defined the PK in the dependent table. If the UserId is also necessary on the PK, include it in the dependent table, and make it part of the FK.

Entity Framework self referencing entity

I have a problem with the Entity Framework.
public class User : Receiver
{
public User()
{
if (Groups == null)
Groups = new List<Group>();
if (Buddies == null)
Buddies = new List<User>();
}
[Required]
public string PhoneNumber { get; set; }
[ForeignKey("Guid"), JsonIgnore]
public IList<User> Buddies { get; set; }
[ForeignKey("Guid"), JsonIgnore]
public IList<Group> Groups { get; set; }
}
public class Receiver
{
public Receiver()
{
Guid = Guid.NewGuid();
Created = DateTime.Now;
}
[Key]
public Guid Guid { get; set; }
[Required]
public DateTime Created { get; set; }
}
When i try to add a user...
User user = new User
{
Guid = new Guid("8cd094c9-e4df-494e-b991-5cf5cc03d6e3"),
PhoneNumber = "+4991276460"
};
cmc.Receivers.Add(user);
... it ends in follogwing error.
The object of the Type "System.Collections.Generic.List`1[Project.Models.User]" can't be converted to "Project.Models.User".
When i comment out following two lines:
[ForeignKey("Guid"), JsonIgnore]
public IList<User> Buddies { get; set; }
...the programm runs fine.
I hope someone can help me to fix this problem.
Otherwise it runs into an error at this line : cmc.Receivers.Add(user);
In your mapping...
[ForeignKey("Guid"), JsonIgnore]
public IList<User> Buddies { get; set; }
...you specify that User.Buddies is part of a one-to-many relationship and that User.Guid (=Receiver.Guid) is the foreign key in this relationship. But User.Guid is also the primary key, hence it must be unique. As a result a User cannot have a list of Buddies but only a single reference.
The mapping makes no sense but the exception is not very helpful and difficult to understand. (Somehow EF seems to recognize internally that the Buddies cannot be a list with that mapping and wants to cast the list to a single reference. It should detect in my opinion that the mapping is invalid in the first place.)
For a correct one-to-many mapping you need a foreign key that is different from the primary key. You can achieve that by either removing the [ForeignKey] annotation altogether...
[JsonIgnore]
public IList<User> Buddies { get; set; }
...in which case EF will create a default foreign key in the Receivers table (it will be some column with an underscore in its name, but you can rename that with Fluent API if you don't like the default name) or by adding your own foreign key property to the User class:
public Guid? BuddyGuid { get; set; }
[ForeignKey("BuddyGuid"), JsonIgnore]
public IList<User> Buddies { get; set; }

Entity Framework CF Fluent API mapping

I have 2 entities:
public class User
{
public int userId { get; set; }
public string name { get; set; }
public Guid userGuid { get; set; }
}
public class Absence
{
public int absenceId { get; set; }
public Guid applicantId { get; set; }
public User applicant { get; set; }
public Guid permitterId{ get; set; }
public User permitter{ get; set; }
...
}
AbsencesConfiguration:
this.HasRequired(u => u.Applicant).WithMany().HasForeignKey(d => d.ApplicantId);
this.HasRequired(u => u.Permitter).WithMany().HasForeignKey(d => d.PermitterId);
I'd like a Fluent API mapping between the two classes, but it gives this error message:
Blockquote\tSystem.Data.Entity.Edm.EdmAssociationConstraint: : The types of all properties in the Dependent Role of a referential constraint must be the same as the corresponding property types in the Principal Role. The type of property 'ApplicantId' on entity 'Absences' does not match the type of property 'UserId' on entity 'User' in the referential constraint 'Absences_Applicant'.
I think this is because EF try to join the two tables with the UserId of the User entity and not with UserGuid column. I thought I would make these two columns of Absence entity unique, but how I can map them together?
Thanks in advance.
The problem is your User primary key is an int, but your foreign key is a Guid.
You need to alter either your User class to have a guid for userId:
public Guid userId { get; set; }
or, update your Absence class to use an int:
public int applicantId { get; set; }

Entity Framework Code First Not Pulling Navigation Property

I have a problem with a navigation property not being loaded. I have this same setup with all my other entities, but this is using a property that isnt a natural FK (Number) and wont cascade, that will be handled by a trigger.
Expression<Func<DivisionBracketGameParticipant, object>>[] includes2 = {
q => q.DivisionWinnerBracketGame,
q => q.DivisionLoserBracketGame
};
var test = _divisionBracketGameParticipantsRepository.GetMany(includes2,
q =>
q.DivisionBracketGame.DivisionBracket.Division.
EventId == eventId);
Database Schema
DivisionBracketGame
Id
Number
DivisionBracketGameParticipant
Id
DivisionBracketGameId -> Id
DivisionBracketGameWinnerNumber -> Number
DivisionBracketGameLoserNumber -> Number
Entities
[Table("DivisionBracketGame", Schema = "GrassrootsHoops")]
public class DivisionBracketGame : BaseEntity
{
public int Id{ get; set; }
public int Number { get; set; }
[InverseProperty("DivisionBracketGame")]
public virtual ICollection<DivisionBracketGameParticipant> DivisionBracketGameParticipants { get; set; }
[InverseProperty("DivisionWinnerBracketGame")]
public virtual ICollection<DivisionBracketGameParticipant> DivisionWinnerBracketGameParticipants { get; set; }
[InverseProperty("DivisionLoserBracketGame")]
public virtual ICollection<DivisionBracketGameParticipant> DivisionLoserBracketGameParticipants { get; set; }
}
[Table("DivisionBracketGameParticipant", Schema = "GrassrootsHoops")]
public class DivisionBracketGameParticipant : BaseEntity
{
public int Id{ get; set; }
public virtual int DivisionBracketGameId { get; set; }
public virtual int? DivisionWinnerBracketGameNumber { get; set; }
public virtual int? DivisionLoserBracketGameNumber { get; set; }
[ForeignKey("DivisionBracketGameId")]
public virtual DivisionBracketGame DivisionBracketGame { get; set; }
[ForeignKey("DivisionWinnerBracketGameNumber")]
public virtual DivisionBracketGame DivisionWinnerBracketGame { get; set; }
[ForeignKey("DivisionLoserBracketGameNumber")]
public virtual DivisionBracketGame DivisionLoserBracketGame { get; set; }
}
EF will not create relation to Number because it is not a primary key. Primary key is of your DivisionBracketGame is Id so both DivisionWinnerBracketGame and DivisionLoserBracketGame are targeting Id (not Number).
One-to-many relation demands that column in principal table is unique - in your case the column should be a Number. This is possible in database by either using primary key from principal table or by using unique index on that column. EF doesn't support unique indexes / candidate keys so the only way to build one-to-many relation in EF is through primary key of principal table.
The FK value is used to get related value so at the moment it probably looks for records with wrong value because it uses a wrong column.

Using two keys in Entity Framework 4, One Identity and one Foreign?

Is it possible to map an Entity with one identity index that auto increments and a foreign key linking it to another table?
public class Item
{
public int ItemID { get; set; }
[StringLength(20)]
public string Barcode { get; set; }
[StringLength(50)]
public string Name { get; set; }
[StringLength(50)]
public string Description { get; set; }
public decimal Price { get; set; }
[ForeignKey("ItemCategory")]
public string CatID { get; set; }
public virtual ItemCategory ItemCategory { get; set; }
}
public class ItemCategory
{
// This should be the identity index
public int ItemCategoryID { get; set; }
// This should be the foreign key
public string CatID { get; set; }
public string Name { get; set; }
public virtual ICollection<Item> Items { get; set; }
}
I saw this answer - should I configure my tables with modelbuilder?
Foreign key in Item must point to primary key in ItemCategory. FKs in EF behave in exactly same way as in databases. It means that FK must point to property with unique values in the principal entity. The problem is that EF doesn't support unique index / constraint so the only way to achieve uniqueness is primary key.
Because of that you cannot point your FK to CatID unless it is part of primary key but in such case you will have composite key containing both ItemCategoryID and CatID and your Item class will have to contain both of them to form correct FK.