Entity Framework Core seed entity problem - c#

I try to add a migration for the below entities and i get the error. I've tried everything to get it to work and i feel like i'm missing something obvious. The code is below
"The seed entity for type 'Bug' cannot be added because no value was provided for the required property 'UserId'"
public class Bug
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int BugId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public Status Status { get; set; }
public DateTime DateCreated { get; set; }
public User User { get; set; }
}
public class User
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
}
modelBuilder.Entity<Bug>().HasData(
new Bug()
{
BugId = 1,
Title = "TestTitle1",
Description = "Test1Description1",
DateCreated = DateTime.Now,
Status = Status.Closed,
User = new User() { UserId = 1, UserName = "TestUser1" },
}
I have tried the above as well as looking up shadow keys and seperating Bug and User entitities

UPDATE:
Thanks for all your suggestions. I spent a few hours today messing about with it and below is how i managed to get it to work in case anyone else comes across this error.
public class User
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string UserName { get; set; }
public ICollection<Bug> Bugs{ get; set; }
}
public class Bug
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public Status Status { get; set; }
public DateTime DateCreated { get; set; }
public User User { get; set; }
public int UserId { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var user1 = new User()
{
Id = 1,
UserName = "TestUsername1"
};
modelBuilder.Entity<User>().HasData(user1);
modelBuilder.Entity<Bug>().HasData(
new Bug()
{
Id = 1,
Title = "TestTitle1",
Description = "TestDescription1",
DateCreated = DateTime.Now,
Status = Status.Open,
UserId = 1,
});
}

Related

Entity Framework cannot add new data on model

i have a project where i work with a bookshop. And when a user buys a book, i want to add a record in the SoldBooks table with info about the book and the user. But everything is fine with the add except when i want to add the User Id. Visual studio wont allow me to add an int "Cannot Implicitly convert type INT to models.User"
db.SoldBooks.Add(new SoldBook
{
Title = book.Title,
Author = book.Author,
Price = book.Price,
PurchaseDate = DateTime.Now,
CategoryId = catid,
User = 1
});
db.SaveChanges();
But when i check my database the field UserId says its an INT
What should i do to be able to add the User ID to a new record? Thank you
Models/User.cs
class User
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Password { get; set; }
public DateTime LastLogin { get; set; }
public DateTime SessionTimer { get; set; }
public bool IsActive { get; set; }
public bool IsAdmin { get; set; }
}
Models/SoldBook.cs
class SoldBook
{
[Key]
public int Id { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public int CategoryId { get; set; }
public int Price { get; set; }
public DateTime PurchaseDate { get; set; }
public User User { get; set; }
}
Make this changes (you have to add info about the ForeignKey so EF can know how both tables are related):
class SoldBook
{
[Key]
public int Id { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public int CategoryId { get; set; }
public int Price { get; set; }
public DateTime PurchaseDate { get; set; }
public int IdUser { get; set; }
[ForeignKey("IdUser")]
public User User { get; set; }
}
and then add the record:
db.SoldBooks.Add(new SoldBook
{
Title = book.Title,
Author = book.Author,
Price = book.Price,
PurchaseDate = DateTime.Now,
CategoryId = catid,
IdUser = 1
});
db.SaveChanges();
You should add additional UserId field to your SoldBook object and use it instead of User
public int UserId { 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; }
}

C# Entity Foreign Key to List Array

I have a class PromoCard and List<PromoCard> PromoCards. Is it possible to map element of List array in Entity Model?
This is my List:
public static List<PromoCard> PromoCards = new List<PromoCard>
{
new PromoCard()
{
Id = 1,
Crystal = 4500,
Price = 100
},
new PromoCard()
{
Id = 2,
Crystal = 24000,
Price = 500
},
new PromoCard()
{
Id = 3,
Crystal = 50000,
Price = 1000
},
};
public class PromoCard
{
[Key]
public int Id { get; set; }
public int Crystal { get; set; }
public int Price { get; set; }
}
And this is my model:
public class BonusCard
{
[Key]
public int Id { get; set; }
public string User_id { get; set; }
[ForeignKey("User_id")]
public virtual ApplicationUser User { get; set; }
public int PromoCard_id { get; set; }
// is there way to link
[ForeignKey("PromoCard_id")]
public virtual PromoCard PromoCard { get; set; }
}
All I had to was change the getter of PromoCard property and put NotMapped Annotation on it
public class BonusCard
{
[Key]
public int Id { get; set; }
public string User_id { get; set; }
[ForeignKey("User_id")]
public virtual ApplicationUser User { get; set; }
public string Code { get; set; }
public DateTime CreationDate { get; set; } = (DateTime)SqlDateTime.MinValue;
public DateTime UsageDate { get; set; } = (DateTime)SqlDateTime.MinValue;
public int? Player_id { get; set; } = null;
[ForeignKey("Player_id")]
public virtual Player Player { get; set; }
public int PromoCard_id { get; set; }
[NotMapped]
public PromoCard PromoCard { get { return PromoCards[PromoCard_id]; } set { } }
}

How to create a foreign relation to one Model from multiple other models using Entity framework?

I am trying to create my first app using ASP.NET MVC framework and Entity Framework 6.
I chose to use code first approach and I started by defining my Models.
I have a model called Client with an identity attribute called Id. I have multiple Models that has an attribute called ClientId. The ClientId attribute should have virtual link to the Clients Model.
Here is how my Client model looks like
[Table("clients")]
public class Client
{
[Key]
public int id { get; set; }
public string name { get; set; }
public string status { get; set; }
public DateTime created_at { get; set; }
public DateTime? modified_at { get; set; }
public Client()
{
status = "Active";
created_at = DateTime.UtcNow;
}
}
Then here is how I am creating a belong to relation using other models.
[Table("BaseClientsToUsers")]
public class ClientToUser : ModelDefault
{
[ForeignKey("User")]
public int UserID { get; set; }
[ForeignKey("Client")]
public int ClientId { get; set; }
[ForeignKey("Team")]
public int DefaultTeamId { get; set; }
public DateTime? JoinedAt { get; set; }
public bool IsActive { get; set; }
public virtual User User { get; set; }
public virtual Client Client { get; set; }
public virtual Team Team { get; set; }
public ClientToUser()
{
DateTime UtcNow = DateTime.UtcNow;
IsActive = true;
CreatedAt = UtcNow;
LastUpdatedAt = UtcNow;
}
[Table("BaseTeams")]
public class Team : ModelDefault
{
[MaxLength(250)]
public string Name { get; set; }
[ForeignKey("Client")]
public int ClientId { get; set; }
public bool IsActive { get; set; }
public virtual Client Client { get; set; }
public Team()
{
DateTime UtcNow = DateTime.UtcNow;
IsActive = true;
CreatedAt = UtcNow;
LastUpdatedAt = UtcNow;
}
}
But, when I try to update my databases I get the following error
Introducing FOREIGN KEY constraint
'FK_dbo.BaseTeams_dbo.BaseClients_ClientId' on table 'BaseTeams' may
cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or
ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. Could
not create constraint or index. See previous errors.
I am not really sure what could be causing the error but it seems it is because I am creating multiple Foreign keys to the same `Clients model.
How can I fix this error?
Hello #Mike A When I started MVC I got this error too, so you need aditional tables that connects your DB items.
So try connect your database items with tables like that:
Here is my working example:
[Table("Products")]
public class Product
{
[Key]
public string Id { get; set; }
[Required]
public string Name { get; set; }
public string Description { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
public decimal InternalPrice { get; set; }
public string Url { get; set; }
}
[Table("Categories")]
public class Category
{
[Key]
public string Id { get; set; }
[Required]
public string Name { get; set; }
public string Url { get; set; }
}
[Table("ProductCategories")]
public class ProductCategory
{
[Key]
[Column(Order = 0)]
public string ProductId { get; set; }
[Key]
[Column(Order = 1)]
public string CategoryId { get; set; }
public virtual Category Category { get; set; }
}
So you can connect your items without problems hope this will help you.

Can't convert from DTO to POCO from one solution to another?

I'm having the strangest problem and I know it's because I'm missing something obvious because this set up works fine when I save data and even pull it down.
My app is set up like so ....
WebUI depends on Business Layer .. Business Layer depends on Data Layer (which is where I'm actually pulling the data). The Business Layer does all the "work".
This is where everything dies (Null Exception, Object Reference not set) as soon as I assign something to userInfo.userData.avatarFilepath (which is not null).
namespace pgl.businesslayer
{
public class userCtx
{
private pgl.datalayer.Concrete.EFDbContext context = new pgl.datalayer.Concrete.EFDbContext();
private pgl.datalayer.Concrete.EFUserContext userContext = new pgl.datalayer.Concrete.EFUserContext();
private pgl.datalayer.Concrete.EFDbCompany companyContext = new pgl.datalayer.Concrete.EFDbCompany();
public ViewModels.UserInfo getUserById(int userId)
{
ViewModels.UserInfo userInfo = new ViewModels.UserInfo();
pgl.datalayer.Dtos.pglUserDTO userDL = userContext.getUserByUserId(userId);
userInfo.userData.avatarFilepath = userDL.avatarFilepath;
userInfo.userData.createdBy = userDL.createdBy;
userInfo.userData.createdDate = userDL.createdDate;
userInfo.userData.email = userDL.email;
userInfo.userData.firstName = userDL.firstName;
userInfo.userData.lastName = userDL.lastName;
etc...
}
ViewModels.UserInfo looks like this...
namespace pgl.businesslayer.ViewModels
{
public class UserInfo
{
// user info
public pgl.businesslayer.Dto.pglUser userData { get; set; }
// salon info
public List<pglSalon> salonsData { get; set; }
// company info
public pglCompany companyData { get; set; }
}
pglUser in the business layer looks like this and is just a POCO
namespace pgl.businesslayer.Dto
{
public class pglUser
{
public int userId { get; set; }
public int companyId { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
public string email { get; set; }
public string username { get; set; }
public byte[] passwordSalt { get; set; }
public byte[] passwordKey { get; set; }
public DateTime createdDate { get; set; }
public int createdBy { get; set; }
public bool passwordResetRequired { get; set; }
public string passwordHash { get; set; }
public string tempPassword { get; set; }
public string userType { get; set; }
public string avatarFilepath { get; set; }
public string timeZone { get; set; }
}
}
And in userContext this is how I am pulling the user data...
public pgl.datalayer.Dtos.pglUserDTO getUserByUserId(int userId)
{
var getUser = (from u in context.pglUser
select new pgl.datalayer.Dtos.pglUserDTO
{
username = u.username,
companyId = u.companyId,
userId = u.userId,
userType = u.userType,
firstName = u.firstName,
lastName = u.lastName,
email = u.email,
createdDate = u.createdDate,
createdBy = u.createdBy,
passwordResetRequired = u.passwordResetRequired,
tempPassword = u.tempPassword,
avatarFilepath = u.avatarFilepath,
timeZone = u.timeZone
}).Where(u => u.userId == userId).FirstOrDefault();
return getUser;
}
pgl.datalayer.Dtos.pglUserDTO looks like this...
namespace pgl.datalayer.Dtos
{
public class pglUserDTO
{
public int userId { get; set; }
public int companyId { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
public string email { get; set; }
public string username { get; set; }
public byte[] passwordSalt { get; set; }
public byte[] passwordKey { get; set; }
public DateTime createdDate { get; set; }
public int createdBy { get; set; }
public bool passwordResetRequired { get; set; }
public string passwordHash { get; set; }
public string tempPassword { get; set; }
public string userType { get; set; }
public string avatarFilepath { get; set; }
public string timeZone { get; set; }
}
}
Even if I assign userInfo.userData.avatarFilepath = "WHATUP!!!" it throws the same error. This has got to be something stupid and simple. I can save data with no problem and when I debug I can see that it is actually pulling the correct user ID and it's associated data. It's just that pgl.businesslayer.ViewModels.UserInfo seems to be un-instantiated. I'm at a loss. I can provide more info... and keep in mind I'm kind of at my wits end so I tried doing weird things like adding (probably) unnecessary DTOs. Any ideas?
You don't appear to be creating the userData object anywhere. When you create a new instance of UserInfo, or in its constructor, try adding:
userData = new pgl.businesslayer.Dto.pglUser();
Or alternatively:
ViewModels.UserInfo userInfo = new ViewModels.UserInfo();
pgl.datalayer.Dtos.pglUserDTO userDL = userContext.getUserByUserId(userId);
userInfo.userData = new pgl.businesslayer.Dto.pglUser {
avatarFilepath = userDL.avatarFilepath,
createdBy = userDL.createdBy,
createdDate = userDL.createdDate,
email = userDL.email,
firstName = userDL.firstName,
lastName = userDL.lastName
};
If you always want to initialise UserInfo with an empty userData member, you could include the creation within the constructor:
namespace pgl.businesslayer.ViewModels
{
public class UserInfo
{
// Default constructor
public UserInfo()
{
userData = new pgl.businesslayer.Dto.pglUser();
}
// user info
public pgl.businesslayer.Dto.pglUser userData { get; set; }
// salon info
public List<pglSalon> salonsData { get; set; }
// company info
public pglCompany companyData { get; set; }
}
}

Categories

Resources