Entity framework code first generate database incorrect - asp.net-mvc-4

I think entity framework has problem while generating database in my project. That's strange that it only happens in one case. This is one to many relationship between "User" and "Playlist". One User has many Playlists.
Here is my code, I used some abstract classes in my project.
Core code
Playlist class
public virtual User User { get; set; }
User class
public virtual ICollection<Playlist> Playlists { get; set; }
The full code:
Generic class:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace xxx.Areas.admin.Models
{
public abstract class Generic
{
[Display(Name = "Ngày tạo")]
public DateTime? Created { get; set; }
[Display(Name = "Lần sửa cuối")]
public DateTime? Modified { get; set; }
[Display(Name = "Trạng thái")]
public bool? IsActive { get; set; }
}
}
Post class:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace xxx.Areas.admin.Models
{
public abstract class Post : Generic
{
public string Title { get; set; }
public string Slug { get; set; }
public string Content { get; set; }
public string Image { get; set; }
public int Views { get; set; }
public bool? AllowComment { get; set; }
public User ModifiedBy { get; set; }
public virtual ICollection<Media> Medias { get; set; }
}
}
AlbumBase class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using xxx.Areas.admin.Models.SongBase;
namespace xxx.Areas.admin.Models.AlbumBase
{
public abstract class AlbumBase : Post
{
public bool IsPublic { get; set; }
public bool IsFeatured { get; set; }
public int OldID { get; set; }
public string OldSlug { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
}
}
Playlist class:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using xxx.Areas.admin.Models.SongBase;
namespace xxx.Areas.admin.Models.AlbumBase
{
public class Playlist : AlbumBase
{
[Key]
public int PlaylistID { get; set; }
public virtual ICollection<Song> Songs { get; set; }
public virtual ICollection<Folk> Folks { get; set; }
public virtual ICollection<Instrumental> Instrumentals { get; set; }
public virtual User User { get; set; }
public Playlist()
{ }
public Playlist(string name)
{
Title = name;
Slug = Functions.URLFriendly(Title);
Views = 0;
OldID = 0;
AllowComment = true;
IsActive = true;
IsPublic = false;
IsFeatured = false;
Created = DateTime.Now;
}
}
}
and User class:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using baicadicungnamthang.Areas.admin.Models.AlbumBase;
using baicadicungnamthang.Areas.admin.Models.Social;
using baicadicungnamthang.DAL;
using ICB;
namespace xxx.Areas.admin.Models
{
public class User : Generic
{
[Key]
public int UserID { get; set; }
[Required(ErrorMessage = "Bạn phải nhập tên tài khoản"), StringLength(50)]
public string UserName { get; set; }
public string Password { get; set; }
public string HashPassword { get; set; }
[Required(ErrorMessage = "Bạn phải nhập địa chỉ email"), EmailAddress(ErrorMessage = "Địa chỉ email không hợp lệ")]
public string Email { get; set; }
[StringLength(50)]
public string NickName { get; set; }
public string FullName { get; set; }
public string Slug { get; set; }
public string Title { get; set; }
public string Phone { get; set; }
public string Avatar { get; set; }
public DateTime? DOB { get; set; }
[StringLength(1)]
public string Gender { get; set; }
public string Address { get; set; }
public int TotalLikes { get; set; }
public int TotalComments { get; set; }
public int Views { get; set; }
public string ActivationKey { get; set; }
public string RecoverKey { get; set; }
public DateTime? LastLogin { get; set; }
public int OldID { get; set; }
public virtual Role Role { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
public virtual ICollection<Comment> RateComments { get; set; }
public virtual ICollection<Playlist> Playlists { get; set; }
public virtual ICollection<User> Friends { get; set; }
public virtual ICollection<Message> MessagesSent { get; set; }
public virtual ICollection<Message> MessagesReceived { get; set; }
public User()
{
Created = DateTime.Now;
IsActive = false;
TotalLikes = 0;
Views = 0;
OldID = 0;
}
public string getAvatar(int w, int h)
{
return Functions.getAvatarThumb(UserName, w, h);
}
public int getAge()
{
if (DOB == null)
{
return 0;
}
else
{
DateTime now = DateTime.Now;
int age = now.Year - DOB.Value.Year;
return age;
}
}
public string getGender()
{
if (Gender == "M")
{
return "Nam";
}
else if (Gender == "F")
{
return "Nữ";
}
else return "";
}
}
}
And this is Playlist table generating from code first:
As you see, entity framework has generated two columns: User_UserID and User_UserID1 from primary key UserID of User table.
I say that because when I uncomment the line
//public virtual User User { get; set; }
and rebuild the project, the two column User_UserID and User_UserID1 has disappeared too.
The problem only happens with User and Playlist relationship. With other one-to-many scenarios (User-Comments), system work well.
Can anyone give me a suggestion?

The problem is that you have multiple relationships between the same entities.
Playlist has 2 references to User (one in the Playlist class and one in its base class Post).
This confuses Entity Framework, because it doesn't know how to map the relationships, which is why it creates too many foreign keys in the database.
To fix this you can use the InverseProperty attribute to tell it how to map the navigation properties:
public class Playlist : AlbumBase
{
[Key]
public int PlaylistID { get; set; }
[InverseProperty("Playlists")]
public virtual User User { get; set; }
......

Related

Model in model is null so modelstate is invalid

I have a model in another model. When I try to check the modelstate it is invalid. This is because the other model in this model is null.
Project.cs:
using System.ComponentModel.DataAnnotations;
namespace Toolbox.Models
{
public class Project
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public WorkPreparation WorkPreparation { get; set; }
}
}
WorkPreparation.cs:
using System.ComponentModel.DataAnnotations;
namespace Toolbox.Models
{
public class WorkPreparation
{
[Key]
public int Id { get; set; }
public int ProjectId { get; set; }
public CentralHeating CentralHeating { get; set; }
public Pluming Pluming { get; set; }
public Ventilation Ventilation { get; set; }
public Project Project { get; set; }
}
}
Does anybody have any suggestion?
If you use .net6, try to remove <Nullable>enable</Nullable> in your project.csproj.

Problem with DbContext prop on asp net core 2.1

I have created an api in asp net core 2.1 and I have three layers inside it (PwP.Web).
In the layer (PWP.DomainClasses) I defined a class with the following specifications and in the layer (PWP.DataLayer) a class called PWPDbContext and inside it I want to define the user class as prop but it warns and is not used, how this Solve the problem?
User.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text;
namespace PWP.DataLayer.User
{
public class User
{
[Key]
[Required]
public int UserId { get; set; }
[Required]
[MaxLength(50)]
public string UserName { get; set; }
[Required]
[MaxLength(32)]
public string Password { get; set; }
[Required]
[MaxLength(150)]
public string Email { get; set; }
[MaxLength(200)]
public string imageAddress { get; set; }
//
public virtual UserInfo.UserInfo UserInfo { get; set; }
}
}
PWPContext.cs:
using Microsoft.EntityFrameworkCore;
using PWP.DomainClasses.user;
namespace PWP.DataLayer.Context
{
class PWPDbContext:DbContext
{
public PWPDbContext(DbContextOptions<PWPDbContext> options): base(options)
{
}
public DbSet<User> Users { get; set; }
public DbSet<UserInfo> UserInfos { get; set; }
public DbSet<Document> Documents { get; set; }
public DbSet<Expertise> Expertises { get; set; }
public DbSet<Message> Messages { get; set; }
public DbSet<Record> Records { get; set; }
public DbSet<STFile> STFiles { get; set; }
}
}
From this line of code:
public virtual UserInfo.UserInfo UserInfo { get; set; }
It can be seen that you named the class with the exact same name as it's namespace.
You should differentiate between them.
Don't (!) do that:
namespace UserInfo
{
public class UserInfo
{
}
}

Fluent NHibernate mapping throws an exception of 'Id is not mapped'

I need help with auto mapping in Fluent Nhibernate. Here's the tables I want to have in my app (they are many of them, but I want to start from mapping only a few of them)
Well, I'd like to use the AutoMapping functionality because I don't want to write the mapping classes for more than 100 tables...
Anyway, here's the error thrown when creating the SessionFactory (the code is at the end of this post)
The entity 'FilterConfig' doesn't have an Id mapped.
Use the Id method to map your identity property. For example: Id(x => x.Id).
Entities (I hope I created them correctly):
public partial class UserLogin
{
public UserLogin()
{
this.UserMessages = new List<UserMessage>();
this.UserMessagesReceivers = new List<UserMessagesReceiver>();
}
public virtual int ID { get; set; }
public virtual int UserTypeID { get; set; }
public virtual int? StudentID { get; set; }
public virtual int? HeadmasterID { get; set; }
public virtual int? ParentID { get; set; }
public virtual string UniqueID { get; set; }
public virtual bool ShowMyPhoneNumber { get; set; }
public virtual bool IsBanned { get; set; }
public virtual string Login { get; set; }
public virtual string Password { get; set; }
public virtual bool WasPasswordSent { get; set; }
public virtual string Email { get; set; }
public virtual string UserPicture { get; set; }
public virtual IList<UserMessage> UserMessages { get; set; }
public virtual IList<UserMessagesReceiver> UserMessagesReceivers { get; set; }
}
public partial class UserMessage
{
public UserMessage()
{
this.UserMessagesReceivers = new List<UserMessagesReceiver>();
this.UserMessagesReplies = new List<UserMessagesReply>();
}
public virtual int ID { get; set; }
public virtual DateTime Date { get; set; }
public virtual DateTime? LastCheckDate { get; set; }
public virtual int UserLoginID { get; set; }
public virtual string Description { get; set; }
public virtual bool HasNonCheckedReplies { get; set; }
public virtual UserLogin UserLogin { get; set; }
public virtual IList<UserMessagesReceiver> UserMessagesReceivers { get; set; }
public virtual IList<UserMessagesReply> UserMessagesReplies { get; set; }
}
public partial class UserMessagesReceiver
{
public UserMessagesReceiver()
{
this.WasMessageChecked = false;
this.UserMessagesReplies = new List<UserMessagesReply>();
}
public virtual int ID { get; set; }
public virtual int UserMessagesID { get; set; }
public virtual int ReceiverLoginID { get; set; }
public virtual bool WasMessageChecked { get; set; }
public virtual DateTime? LastCheckedDate { get; set; }
public virtual UserLogin UserLogin { get; set; }
public virtual UserMessage UserMessage { get; set; }
public virtual IList<UserMessagesReply> UserMessagesReplies { get; set; }
}
public partial class UserMessagesReply
{
public UserMessagesReply()
{
}
public virtual int ID { get; set; }
public virtual DateTime Date { get; set; }
public virtual int UserMessagesID { get; set; }
public virtual int? UserMessagesReceiverID { get; set; }
public virtual string Description { get; set; }
public virtual UserMessage UserMessage { get; set; }
public virtual UserMessagesReceiver UserMessagesReceiver { get; set; }
}
Configuration:
public class AutomappingConfiguration : DefaultAutomappingConfiguration
{
public override bool IsId(Member member)
{
return member.Name == member.DeclaringType.Name + "ID";
}
}
private static AutoPersistenceModel CreateAutomappings()
{
return AutoMap.AssemblyOf<AutomappingConfiguration>(new AutomappingConfiguration());
}
private static ISessionFactory CreateSessionFactory()
{
var cfg = new AutomappingConfiguration();
return Fluently.Configure()
.Database(MySQLConfiguration.Standard
.ConnectionString("..."))
.Mappings(m => m.AutoMappings
.Add(AutoMap.AssemblyOf<UserLogin>(cfg))
.Add(AutoMap.AssemblyOf<UserMessage>(cfg))
.Add(AutoMap.AssemblyOf<UserMessagesReceiver>(cfg))
.Add(AutoMap.AssemblyOf<UserMessagesReply>(cfg)))
.BuildSessionFactory();
}
in the configuration you said that the Ids are named like UserLoginID but in the class they are defined as public virtual int ID { get; set; } so change
return member.Name == member.DeclaringType.Name + "ID";
to
return member.Name == "ID";
Some additional info:
CreateAutomappings() seems to be not used
AutomappingConfiguration should at least override ShouldMap(Member) to filter on the namespace (e.g. member.Namespace.StartsWith(typeof(UserMessage).Namespace)) otherwise sooner or later utility classes and the like will be mapped as well
AutoMap.AssemblyOf<> should be called per assembly containing types not per type

LINQ Query Syntax (getting error)

I am trying to understand the syntax of a LINQ query. I tried creating one to select all rows from my TRACK_INFO table where the column collegeOf was equal to a variable. My database name is KuPlan. Below is the query I tried to create and my TRACK_INFO model. The error i get is: "could not find an implementation of the query pattern for source type KU_PLAN_DEV.Models.TRACK_INFO. 'Where' not found."
controller:
var query = from degreeName in TRACK_INFO
where degreeName == trackButton
select degreeName;
model:
namespace KU_PLAN_DEV.Models
{
using System;
using System.Collections.Generic;
public partial class TRACK_INFO
{
public TRACK_INFO()
{
this.CORE_HEAD = new HashSet<CORE_HEAD>();
this.GEN_ED_HEAD = new HashSet<GEN_ED_HEAD>();
this.GEN_ED_NOTE = new HashSet<GEN_ED_NOTE>();
this.GRAD_CLEAR_HEAD = new HashSet<GRAD_CLEAR_HEAD>();
this.MAJOR_NOTE = new HashSet<MAJOR_NOTE>();
}
public string progNum { get; set; }
public string versionNum { get; set; }
public string degreeName { get; set; }
public string collegeOf { get; set; }
public string effectiveDateTerm { get; set; }
public Nullable<decimal> effectiveDateYear { get; set; }
public string trackDegreeType { get; set; }
public virtual ICollection<CORE_HEAD> CORE_HEAD { get; set; }
public virtual ICollection<GEN_ED_HEAD> GEN_ED_HEAD { get; set; }
public virtual ICollection<GEN_ED_NOTE> GEN_ED_NOTE { get; set; }
public virtual ICollection<GRAD_CLEAR_HEAD> GRAD_CLEAR_HEAD { get; set; }
public virtual GRAD_CLEAR_SIG_DATE GRAD_CLEAR_SIG_DATE { get; set; }
public virtual ICollection<MAJOR_NOTE> MAJOR_NOTE { get; set; }
}
}
TRACK_INFO is a class name, not an IEnumerable<TRACK_INFO>. I think you meant to get a property off of your context:
from degreeName in context.TRACK_INFO
...

Date fields are always required in MVC Scaffolding

I have a model where i have scaffold it with Mvc Scaffolding, All Fields with DateTime Property in my model are marked as Required i mean i can not enter a null value in it. Even though in my model there is no [Required] attribute for Date fields. I want to get rid of this issue, any idea?
Here is my Model.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MVCMembershipBootstrap.Models.FirstComponent
{
public class FirstCmActivity
{
public int FirstCmActivityId { get; set; }
public string Name { get; set; }
public DateTime PlannedStartDate { get; set; }
public DateTime PlannedEndDate { get; set; }
public DateTime OngoingStartDate { get; set; }
public DateTime OngoingEndDate { get; set; }
public DateTime FinishedDate { get; set; }
public string GizResponsible { get; set; }
public string PartnerResponsible { get; set; }
public string swAfghanSide { get; set; }
public string swGiz { get; set; }
public string swRodeco { get; set; }
public string swExtern { get; set; }
public string EquipmentNeeds { get; set; }
public string EquipmentExist { get; set; }
public string MileStone { get; set; }
public int FirstCmOutputId { get; set; }
public virtual FirstCmOutput Output { get; set; }
}
}
Here is My Controller...
public class FirstCmActivitiesController : Controller
{
private OPandMEContext context = new OPandMEContext();
//
// GET: /FirstCmActivities/
public ViewResult Index()
{
return View(context.FirstCmActivities.ToList());
}
public ViewResult Report()
{
return View();
}
//
// GET: /FirstCmActivities/Details/5
public ViewResult Details(int id)
{
FirstCmActivity firstcmactivity = context.FirstCmActivities.Single(x => x.FirstCmActivityId == id);
return View(firstcmactivity);
}
//
// GET: /FirstCmActivities/Create
public ActionResult Create()
{
ViewBag.PossibleFirstCmOutputs = context.FirstCmOutputs;
return View();
}
//
// POST: /FirstCmActivities/Create
[HttpPost]
public ActionResult Create(FirstCmActivity firstcmactivity)
{
if (ModelState.IsValid)
{
context.FirstCmActivities.Add(firstcmactivity);
context.SaveChanges();
Response.Redirect("http://localhost:53785/firstcmActivities/Create#services");
}
ViewBag.PossibleFirstCmOutputs = context.FirstCmOutputs;
return View(firstcmactivity);
}
Thanks
Just Correct your properties of Datetime as nullable.
Example :-
public DateTime? PlannedStartDate { get; set; }