Linq2db AssociationAttribute implementation returns an error - c#

I have been trying to get related data by using Linq2db LoadWith extension method. My purpose is getting a user's posts by using LoadWith extension method.
It returns an error that says like this.
LinqToDB.Linq.LinqException: 'Expression 'Param_0.CreatedBy' is not a Field.' but Post entity class has a property that is called CreatedBy.
Here is my AppUser class.
public class AppUser : BaseEntity, IAppUser
{
[Required, Identity]
[Key]
public new int Id { get; set; }
[Required]
[ForeignKey("UserDetail")]
public int DetailId { get; set; }
[LinqToDBAssociation.Association(ThisKey = nameof(DetailId), OtherKey = nameof(AppUserDetail.Id), CanBeNull = true, Relationship = Relationship.OneToOne)]
public virtual AppUserDetail UserDetail { get; set; }
public string UserName { get; set; }
public string NormalizedUserName { get; set; }
public string PasswordHash { get; set; }
public bool EmailConfirmed { get; set; }
public string Email { get; set; }
public string NormalizedEmail { get; set; }
public DateTimeOffset? LockoutEnd { get; set; }
public int AccessFailedCount { get; set; }
public bool LockoutEnabled { get; set; }
public string PhoneNumber { get; set; }
public bool PhoneNumberConfirmed { get; set; }
public string SecurityStamp { get; set; }
public bool TwoFactorEnabled { get; set; }
public string ConcurrencyStamp { get; set; }
[LinqToDBAssociation.Association(ThisKey = nameof(Id), OtherKey = nameof(Post.CreatedBy), CanBeNull = true)]
public virtual IEnumerable<Post> UserPosts { get; set; }
}
Here is my Post class.
public class Post : BaseEntity
{
public Post()
{
PostImages = new HashSet<PostImage>();
PostComments = new HashSet<PostComment>();
PostVideos = new HashSet<PostVideo>();
}
public string Text { get; set; }
public int? PostType { get; set; }
public virtual ICollection<PostComment> PostComments { get; set; }
public virtual ICollection<PostImage> PostImages { get; set; }
public virtual ICollection<PostVideo> PostVideos { get; set; }
}
Here is my BaseEntity class.
public class BaseEntity : IEntity
{
public int Id { get; set; }
[ForeignKey("CreatedUser")] //By using CreatedUser integration, an owner of post,postComment,postLike that has been created, can be found easily thanks to it.
public virtual int? CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
[ForeignKey("ModifiedUser")] //ModifiedUser can be used in AdminUI.
public int? ModifiedBy { get; set; }
public DateTime? ModifiedDate { get; set; }
public int? StatusId { get; set; } //This can be Enumerations.
public BaseEntity()
{
CreatedDate = DateTime.Now;
}
public virtual AppUser CreatedUser { get; set; }
public virtual AppUser ModifiedUser { get; set; }
}
This LoadWith extension method returns that error.
var appUser = _appUserRepository.Table.LoadWith(p => p.UserPosts).FirstOrDefault(x => x.UserName == userName);
If you would like to see the project, you can check here;
https://github.com/dogaanismail/DevPlatform
How can I handle it ?
Best Regards

I suppose you need to add [LinqToDB.Mapping.Column] attribute to your properties or set [Table(IsColumnAttributeRequired = false)] for whole entity.
I encountered the same exception and found a solution at this issue in the library repository.

Related

C# Unable to track entity of type because primary key property is null

I have a User table and a UserProfileImage table that is linked together.
This is the User table structure
public class User : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string MobileNumber { get; set; }
public override bool LockoutEnabled { get; set; } = true;
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? DateOfBirth { get; set; }
public DateTime CreatedOn { get; set; } = DateTime.Now;
public DateTime UpdatedOn { get; set; } = DateTime.Now;
public UserProfileImage UserProfileImage { get; } = new UserProfileImage();
}
This is the UserProfileImage structure
public class UserProfileImage
{
[Key]
public string Id { get; set; }
public string Name { get; set; }
public string UserId { get; set; }
public virtual User User { get; set; }
public string Link { get; set; }
public string Location { get; set; }
public DateTime CreatedOn { get; set; } = DateTime.Now;
}
I have linked them in the dbcontext like this:
modelBuilder.Entity<User>()
.HasOne(a => a.UserProfileImage)
.WithOne(b => b.User)
.HasForeignKey<UserProfileImage>(b => b.UserId)
.OnDelete(DeleteBehavior.Cascade);
However, when I try to add a new user, I get this exception:
Unable to track an entity of type 'UserProfileImage' because primary
key property 'Id' is null.
May I know what does this mean? I am not adding a new entry to UserProfileImage at the moment.
try to fix your classes:
ublic class User : IdentityUser
{
......
public string UserProfileImageId { get; set;}
[ForeignKey(nameof(UserProfileImageId ))]
[InverseProperty("User")]
public virtual UserProfileImage UserProfileImage { get; set;}
}
public class UserProfileImage
{
[Key]
public string Id { get; set; }
......
[InverseProperty("UserProfileImage")]
public virtual User User { get; set;}
}

Reference to application users always returning null even though included

My Club has many members so I have added the following virtual property Members my question is when I want to list the club members shouldn't adding just the virtual load this into lazy loading am using .net 5.0.1 at present.
var members = _context.Clubs.Include(c=>c.Members).Where(w => w.ClubId == tennantId ).ToList();
When I look at var members even when the members have been included it is zero even though the teannatId matches.
public class MSFSAddonDBContext : IdentityDbContext<ApplicationUser>
{
public MSFSAddonDBContext(DbContextOptions<MSFSAddonDBContext> options)
: base(options)
{
}
public DbSet<Club> Clubs { get; set; }
public virtual List<ApplicationUser>? Members { get; set; }
}
This is my controller method.
public void IActionResult ClubMembers()
{
var tennantId = GetTennantId().Result;
var members = _context.Clubs.Include(c=>c.Members).Where(w => w.ClubId == tennantId ).ToList();
return View(members);
}
There are two members references at top level and inside the clubs.
This is the club class
public class Club
{
public int Id { get; set; }
public Guid? TeannatId { get; set; }
public Guid? ClubId { get; set; }
public Guid? UserId { get; set; }
public string? Name { get; set; }
public string? Description { get; set; }
public string? Url { get; set; }
public int? ClubLikes { get; set; }
public int? ClubDislikes { get; set; }
public int? MembersCount { get; set; }
public string? Logo { get; set; }
public List<Flight>? Flights { get; set; }
public string? ThumbNail { get; set; }
public DateTimeOffset? GpdrRemoveRequestDate { get; set; }
public bool? isGpdrRemoveRequest { get; set; }
public DateTimeOffset? BannedTime { get; set; }
public TimeSpan? BanPeriod { get; set; }
public bool? isBanned { get; set; }
public bool? isActive { get; set; }
public bool? isDeleted { get; set; }
public DateTime? CreatedDate { get; set; }
public string? CreatedBy { get; set; }
public virtual List<ApplicationUser>? Members { get; set; }
}
Edit 2
This is the application user class.
public class ApplicationUser : IdentityUser
{
public enum UserTypeEnum
{
Guest=0,
User=1,
Author=2,
AddonOwner=3,
GroupOwner=5,
ClubMember=6,
ClubAdmin=7,
SuperAdmin=199,
BandUser=999
}
public string? FirstName { get; set; }
public string? LastName { get; set; }
public string? GamerTag { get; set; }
public bool? isOnline { get; set; }
public int? UserType { get; set; }
public Guid? TennantId { get; set; }
public Guid? ClubId { get; set; }
public List<Badges>? Badges { get; set; }
}
NB As always with ef the primary keys in all my tables are the Id column thanks

Why is my entity type association being severed?

So I am currently attempting to seed the dev database with test info for our developers, but I am running into this issue - The association between entity types 'UserProfile' and 'ProjectProgress' has been severed but the relationship is either marked as 'Required' or is implicitly required because the foreign key is not nullable. If the dependent/child entity should be deleted when a required relationship is severed, then setup the relationship to use cascade deletes. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the key values.
User Profile Model -
public int UserProfileId { get; set; }
public UserProfileStatus UserProfileStatusId { get; set; } = UserProfileStatus.Active;
public SiteRole SiteRoleId { get; set; }
[MaxLength(100)]
public string Username { get; set; }
[MaxLength(50)]
public string Password { get; set; }
[MaxLength(100)]
public string FirstName { get; set; }
[MaxLength(100)]
public string LastName { get; set; }
[MaxLength(20)]
public string Phone { get; set; }
[MaxLength(150)]
public string Email { get; set; }
public DateTime PasswordChangeDt { get; set; } = DateTime.UtcNow;
public DateTime? LastLoginDt { get; set; }
public int InvalidLogins { get; set; }
public bool Locked { get; set; }
public DateTime? LockoutEnd { get; set; } //local copy of auth db value
public bool Analyst { get; set; }
public bool Reviewer { get; set; }
public bool Broker { get; set; }
public bool EmailGlobalStatusAlerts { get; set; }
public bool EmailReviewerStatusAlerts { get; set; }
public bool EmailAssignedStatusAlerts { get; set; }
public bool Active { get; set; }
public int? BankId { get; set; }
public int AddBy { get; set; }
public DateTime AddDt { get; set; } = DateTime.UtcNow;
public int ModBy { get; set; }
public DateTime ModDt { get; set; } = DateTime.UtcNow;
public virtual Bank Bank { get; set; }
[InverseProperty(nameof(ReviewerAnalyst.Analyst))]
public virtual ICollection<ReviewerAnalyst> AnalystReviewers { get; set; } = new
List<ReviewerAnalyst>();
[InverseProperty(nameof(DocumentAccessLog.AccessUser))]
public virtual ICollection<DocumentAccessLog> DocumentAccessLogs { get; set; } = new
List<DocumentAccessLog>();
public virtual ICollection<EmailLog> EmailLogs { get; set; } = new List<EmailLog>();
public virtual ICollection<Note> Notes { get; set; } = new List<Note>();
[InverseProperty(nameof(Project.Analyst))]
public virtual ICollection<Project> ProjectAnalyst { get; set; } = new List<Project>();
[InverseProperty(nameof(Project.Reviewer))]
public virtual ICollection<Project> ProjectReviewer { get; set; } = new List<Project>();
[InverseProperty(nameof(ReviewerAnalyst.Reviewer))]
public virtual ICollection<ReviewerAnalyst> ReviewerAnalysts { get; set; } = new
List<ReviewerAnalyst>();
public virtual ICollection<TimeOff> TimeOffs { get; set; } = new List<TimeOff>();
[InverseProperty(nameof(TimeOff.Approver))]
public virtual ICollection<TimeOff> TimeOffApprovals { get; set; } = new List<TimeOff>();
public virtual ICollection<UserEmailType> UserEmailTypes { get; set; } = new
List<UserEmailType>();
public virtual ICollection<UserRole> UserRoles { get; set; } = new List<UserRole>();
ProjectProgress Model -
public int ProjectProgressId { get; set; }
public int ProjectId { get; set; }
public int ProgressId { get; set; }
[MaxLength(250)]
public string Notes { get; set; }
public bool Complete { get; set; }
public int AddBy { get; set; }
public System.DateTime AddDt { get; set; }
public virtual Project Project { get; set; }
public virtual Progress Progress { get; set; }
[ForeignKey("AddBy")]
public virtual UserProfile UserProfile { get; set; }
I don't know exactly is needed to help troubleshoot this issue, but let me know and I will update the question.
Check the documentation on cascade delete
For the second action above, setting a foreign key value to null is not valid if foreign key is not nullable. (A non-nullable foreign key is equivalent to a required relationship.) In these cases, EF Core tracks that the foreign key property has been marked as null until SaveChanges is called, at which time an exception is thrown because the change cannot be persisted to the database. This is similar to getting a constraint violation from the database.
Try changing the ProjectProgress as follows, by making the AddBy nullable like this:
public calss ProjectProgress {
public int ProjectProgressId { get; set; }
public int ProjectId { get; set; }
public int ProgressId { get; set; }
[MaxLength(250)]
public string Notes { get; set; }
public bool Complete { get; set; }
public int? AddBy { get; set; }
public System.DateTime AddDt { get; set; }
public virtual Project Project { get; set; }
public virtual Progress Progress { get; set; }
[ForeignKey("AddBy")]
public virtual UserProfile UserProfile { get; set; }
}

How to fix SqlException: Invalid column name

I'm using EF code first migrations in MVC5 with SQL Server.
I created a post method, I'm posting DTO data from the client and its all fine i believe, but when i try to save the data to the db i get this invalid column name exception on a foreign key property.
This is the first time i actually counter this error. I checked other questions and most answers were related to the [ForeignKey] data annotation but i think i implemented it the right way
This is the Model
public class ServiceProvider
{
public Guid Id { get; set; }
public string Name { get; set; }
public string PhoneNumber { get; set; }
public double YearsOfExperiance { get; set; }
public double AverageRank { get; set; }
public string Nationality { get; set; }
public ICollection<JobImage> JobImages { get; set; }
public ICollection<Review> Reviews { get; set; }
public ICollection<Rank> Ranks { get; set; }
public bool Active { get; set; }
[ForeignKey("Category")]
public int CategoryId { get; set; }
public Category Category { get; set; }
public bool Approved { get; set; }
}
This is the controller ActionResult method
[HttpPost]
public ActionResult AddServiceProvider(ServiceProviderDTO serviceProvider)
{
bool isInDb = _context.ServiceProviders.Any(s => s.Name == serviceProvider.Name) ? true : false;
//var serviceProviderInDb = _context.ServiceProviders.Where(s => s.Name == serviceProvider.Name).FirstOrDefault();
var newServiceProvider = new ServiceProvider();
if (isInDb == false)
{
newServiceProvider = new ServiceProvider
{
Id = Guid.NewGuid(),
Name = serviceProvider.Name,
PhoneNumber = serviceProvider.PhoneNumber,
YearsOfExperiance = serviceProvider.YearsOfExperiance,
Nationality = serviceProvider.Nationality,
CategoryId = serviceProvider.CategoryId,
Active = true,
Approved = serviceProvider.Approved == null ? false : serviceProvider.Approved.Value
};
_context.ServiceProviders.Add(newServiceProvider);
_context.SaveChanges();
}
return RedirectToAction("Index", "Home");
}
The error occurs on _context.SaveChanges();
It states that CategoryId is an invalid column name
This is not the first time that i use code first migrations and i never came across this error before so i really have no idea why this happens!
I would have the model like this.
The ForeignKey attribute belong to the Category property
public class ServiceProvider
{
public Guid Id { get; set; }
public string Name { get; set; }
public string PhoneNumber { get; set; }
public double YearsOfExperiance { get; set; }
public double AverageRank { get; set; }
public string Nationality { get; set; }
public ICollection<JobImage> JobImages { get; set; }
public ICollection<Review> Reviews { get; set; }
public ICollection<Rank> Ranks { get; set; }
public bool Active { get; set; }
public int CategoryId { get; set; }
[ForeignKey("CategoryId")]
public Category Category { get; set; }
public bool Approved { get; set; }
}
you need delete this property public int CategoryId { get; set; }
your property public Category Category { get; set; } is the ForeignKey and add the DataAnnotations [ForeignKey("CategoryId")]
it would look like this
public class ServiceProvider
{
public Guid Id { get; set; }
public string Name { get; set; }
public string PhoneNumber { get; set; }
public double YearsOfExperiance { get; set; }
public double AverageRank { get; set; }
public string Nationality { get; set; }
public ICollection<JobImage> JobImages { get; set; }
public ICollection<Review> Reviews { get; set; }
public ICollection<Rank> Ranks { get; set; }
public bool Active { get; set; }
[ForeignKey("Category")]
public int CategoryId { get; set; }
public Category Category { get; set; }
public bool Approved { get; set; }
}

How to fix System.InvalidOperationException error?

I am trying to join two tables using Entity Framework but getting System.InvalidOperationException error. The error message is:
The property 'MasterCompany' is not a navigation property of entity type 'UnitOfMeasure'. The 'Include(string)' method can only be used with a '.' separated list of navigation property names.`.
I am not sure why it is throwing it.
Other Attempts:
I also tried adding public virtual MasterCompany MasterCompany { get; set; } in UnitOfMeasure but that throws Invalid column error.
Also added [Key] in MasterCompany table for MasterCompanyId.
But both of these changes throws Invalid column name 'IsDeleted'. error.
DAL Models:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string>
{
public DbSet<UnitOfMeasure> UnitOfMeasure { get; set; }
public DbSet<MasterCompany> MasterCompany { get; set; }
}
public class UnitOfMeasure : PasBase, IAudit
{
[Key]
public long UnitOfMeasureId { get; set; }
public string Description { get; set; }
public string ShortName { get; set; }
public string Memo { get; set; }
public string Standard { get; set; }
// [ForeignKey("MasterCompanyId")]
public Int32 MasterCompanyId { get; set; }
public bool IsActive { get; set; }
public bool IsDeleted { get; set; }
[NotMapped]
public string UploadStatus { get; set; }
[ForeignKey("MasterCompanyId")]
public virtual MasterCompany MasterCompany { get; set; }
}
public class MasterCompany:AuditableEntity
{
public int MasterCompanyId { get; set; }
public string CompanyName { get; set; }
public string TaxId { get; set; }
public string EmailAddress { get; set; }
public string Address { get; set; }
public bool? IsActive { get; set; }
}
Repository:
private ApplicationDbContext _appContext => (ApplicationDbContext)_context;
public IEnumerable<DAL.Models.UnitOfMeasure> getUnitOfMeasureData()
{
return _appContext.UnitOfMeasure
.Include("MasterCompany")
.Where(c => c.IsDeleted == false || c.IsDeleted == null)
.OrderByDescending(c => c.UnitOfMeasureId)
.ToList();
}
You need to add a MasterCompany property in the class UnitOfMeasure
public class UnitOfMeasure : PasBase, IAudit
{
[Key]
public long UnitOfMeasureId { get; set; }
public string Description { get; set; }
public string ShortName { get; set; }
public string Memo { get; set; }
public string Standard { get; set; }
public Int32 MasterCompanyId { get; set; }
[ForeignKey("MasterCompanyId")]
public MasterCompany MasterCompany { get; set; }
public bool IsActive { get; set; }
public bool IsDeleted { get; set; }
[NotMapped]
public string UploadStatus { get; set; }
}

Categories

Resources