I have a learner table that i set values to on a user registration, 'Register(RegisterViewModel model)' in the AccountController.
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
using (The_FactoryDBContext db = new The_FactoryDBContext())
{
Learner learner = new Learner();
learner.learnerID = User.Identity.GetUserId();
learner.llCounter = 0;
learner.dtwCounter = 0;
learner.ftwCounter = 0;
learner.counter = 0;
db.Learners.Add(learner);
db.SaveChanges();
}
}
}
This is how my learner auto generated class looks with some virtual fields.
public partial class Learner
{
public Learner()
{
this.Learner_Treasure = new HashSet<Learner_Treasure>();
}
public string learnerID { get; set; }
public int llCounter { get; set; }
public int dtwCounter { get; set; }
public int ftwCounter { get; set; }
public int counter { get; set; }
public virtual AspNetUser AspNetUser { get; set; }
public virtual ICollection<Learner_Treasure> Learner_Treasure { get; set; }
}
}
However i get this error upon registration and i dont know how to fix it, can someone help me, or is my code perhaps in the wrong place?
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Learner_AspNetUsers1". The conflict occurred in database "The_Factory", table "dbo.AspNetUsers", column 'Id'.
AspNetUser class
public partial class AspNetUser
{
public AspNetUser()
{
this.AspNetUserClaims = new HashSet<AspNetUserClaim>();
this.AspNetUserLogins = new HashSet<AspNetUserLogin>();
this.AspNetRoles = new HashSet<AspNetRole>();
}
public string Id { get; set; }
public string Email { get; set; }
public bool EmailConfirmed { get; set; }
public string PasswordHash { get; set; }
public string SecurityStamp { get; set; }
public string PhoneNumber { get; set; }
public bool PhoneNumberConfirmed { get; set; }
public bool TwoFactorEnabled { get; set; }
public Nullable<System.DateTime> LockoutEndDateUtc { get; set; }
public bool LockoutEnabled { get; set; }
public int AccessFailedCount { get; set; }
public string UserName { get; set; }
public int AvatarID { get; set; }
public virtual ICollection<AspNetUserClaim> AspNetUserClaims { get; set; }
public virtual ICollection<AspNetUserLogin> AspNetUserLogins { get; set; }
public virtual Avatar Avatar { get; set; }
public virtual Learner Learner { get; set; }
public virtual ICollection<AspNetRole> AspNetRoles { get; set; }
}
}
Try with
[ForeignKey("AspNetUser")]
over learnerID property. The reason is that EF has no clue that you are creating a 1-1 mapping from learner to user (and that the PK in learner is also the FK to user). Putting this attribute will tell EF about your design.
Related
I have a problem with related entities deletion. For example, I need to delete one of series from user series collection. When this happens I want all of related to this series records in database to be deleted. How to do it? Please provide example, I'm stuck a little. Thank you!
public class User
{
public Guid UserId { get; set; }
public virtual List<Series> UserSeries { get; set; }
}
public class DropPhoto
{
public Guid DropPhotoId { get; set; }
public virtual SimpleLine SimpleHorizontalLine { get; set; }
public virtual SimpleLine SimpleVerticalLine { get; set; }
public virtual Drop Drop { get; set; }
}
public class ReferencePhoto
{
public Guid ReferencePhotoId { get; set; }
public virtual SimpleLine SimpleLine { get; set; }
}
public class Series
{
public Guid SeriesId { get; set; }
public virtual List<DropPhoto> DropPhotosSeries { get; set; }
public virtual ReferencePhoto ReferencePhotoForSeries { get; set; }
}
public class SimpleLine
{
public Guid SimpleLineId { get; set; }
}
public class Drop
{
public Guid DropId { get; set; }
}
You are actually looking for cascade delete.
For details please look at https://www.entityframeworktutorial.net/code-first/cascade-delete-in-code-first.aspx
Here is an example
public class Student
{
public int StudentId { get; set; }
public string StudentName { get; set; }
public virtual StudentAddress Address { get; set; }
}
public class StudentAddress
{
[ForeignKey("Student")]
public int StudentAddressId { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public int Zipcode { get; set; }
public string State { get; set; }
public string Country { get; set; }
public virtual Student Student { get; set; }
}
The following example demonstrates the cascade delete operation
using (var ctx = new SchoolContext())
{
var stud = new Student() { StudentName = "James" };
var add = new StudentAddress() { Address1 = "address" };
stud.Address = add;
ctx.Students.Add(stud);
ctx.SaveChanges();
ctx.Students.Remove(stud);// student and its address will be removed from db
ctx.SaveChanges();
}
I have the following two classes:
public class Record
{
public int RecordId { get; set; }
public DateTime? InsertDate { get; set; } = DateTime.Now;
public DateTime BookingDate { get; set; }
public string AmountTypeName { get; set; }
public double? Amount { get; set; }
public string BookingAccountID { get; set; }
public string AccountCurrency { get; set; }
public string ClientCurrency { get; set; }
public string AffectsBalance { get; set; }
public double? AmountAccountCurrency { get; set; }
public string AmountClientCurrency { get; set; }
public int UnifiedInstrumentCode { get; set; }
public InstrumentInfo InstrumentInfo { get; set; }
}
public class InstrumentInfo
{
[Key]
public int UnifiedInstrumentCode { get; set; }
public ICollection<Record> Record { get; set; }
public string AssetType { get; set; }
public int UnderlyingInstrumentUic { get; set; }
public string UnderlyingInstrumentSubType { get; set; }
public string InstrumentSymbol { get; set; }
public string InstrumentDescription { get; set; }
public string InstrumentSubType { get; set; }
public string UnderlyingInstrumentAssetType { get; set; }
public string UnderlyingInstrumentDescription { get; set; }
public string UnderlyingInstrumentSymbol { get; set; }
}
that I want to use as my context for EF6.
I defined the context the following way:
public class TransactionsContext: DbContext
{
public DbSet<Record> Records { get; set; }
public DbSet<InstrumentInfo> InstrumentInfos { get; set; }
public TransactionsContext()
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer<TransactionsContext>(null);
base.OnModelCreating(modelBuilder);
}
}
If I run a test against it that shall add and InstrumentInfo object to the DB
[TestMethod]
public void AddInstrumentInfo_Added_IsTrue()
{
InstrumentInfo info = FakeFactory.GetInstrumentInfo();
using (var ctx = new TransactionsContext())
{
ctx.InstrumentInfos.Add(info);
ctx.SaveChanges();
}
}
I get the following exception:
SqlException: Cannot insert the value NULL into column
'UnifiedInstrumentCode', table
'TransactionsContext.dbo.InstrumentInfoes'; column does not allow
nulls. INSERT fails. The statement has been terminated.
I tried all different scenarios that I found here but I couldn't figure out what I'm doing wrong.
The ultimate goal is that i define my two classes in a way so that a "Record" is linked to the "InstrumentInfo" table via the "UnifiedInstrumentCode" property.
My guess is that my constraints for this two tables are still not correct, but I cant figure out how to define it in EF6 (code first) to get this working.
Adding the annotation [DatabaseGenerated(DatabaseGeneratedOption.None)] to my primary key in InstrumentInfo solved the problem:
public class InstrumentInfo
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int UnifiedInstrumentCode { get; set; }
public ICollection<Record> Record { get; set; }
public string AssetType { get; set; }
public int UnderlyingInstrumentUic { get; set; }
public string UnderlyingInstrumentSubType { get; set; }
public string InstrumentSymbol { get; set; }
public string InstrumentDescription { get; set; }
public string InstrumentSubType { get; set; }
public string UnderlyingInstrumentAssetType { get; set; }
public string UnderlyingInstrumentDescription { get; set; }
public string UnderlyingInstrumentSymbol { get; set; }
}
I did not investigate further but my guess is that if a new Record is added, EF initially creates and InstrumentInfo object that has a Null Value for its Primary key which causes the Exception.
I hope it helps if somebody runs into the same problem in future.
I am trying to add an entry to a table that holds a users browsing history information. However, when trying to save the addition an SqlException is thrown:
Cannot insert duplicate key row in object 'dbo.AspNetUsers' with
unique index 'UserNameIndex'. The duplicate key value is
(exampleUserName). The statement has been terminated.
A user is has many browsing histories but a browsing history can only be attached to one user so there is a user as part of the BrowsingHistory DataModel:
namespace DataModels
{
[Table("BrowsingHistory")]
public class BrowsingHistory
{
[Key]
public int BrowsingHistoryId { get; set; }
public int ProductId { get; set; }
public System.DateTime DateTime { get; set; }
public int DeviceId { get; set; }
public int UserId { get; set; }
public virtual AspNetUsers User { get; set; }
public virtual Device Device { get; set; }
public virtual Product Product { get; set; }
}
}
It is to note that I am using the Microsoft Identity classes for my authentication. The user class looks as follows:
namespace DataModels
{
using System;
using System.Collections.Generic;
[Table("AspNetUsers")]
public class AspNetUsers
{
public AspNetUsers()
{
BrowsingHistories = new HashSet<BrowsingHistory>();
Orders = new HashSet<Order>();
AspNetUserClaims = new HashSet<AspNetUserClaims>();
AspNetRoles = new HashSet<AspNetRoles>();
}
[Key]
public int Id { get; set; }
public string Email { get; set; }
public bool EmailConfirmed { get; set; }
public string PasswordHash { get; set; }
public string SecurityStamp { get; set; }
public string PhoneNumber { get; set; }
public bool PhoneNumberConfirmed { get; set; }
public bool TwoFactorEnabled { get; set; }
public DateTime? LockoutEndDateUtc { get; set; }
public bool LockoutEnabled { get; set; }
public int AccessFailedCount { get; set; }
public string UserName { get; set; }
public string HouseName { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
public string Town { get; set; }
public string County { get; set; }
public string Postcode { get; set; }
public string ContactNumber { get; set; }
public virtual ICollection<BrowsingHistory> BrowsingHistories { get; set; }
public virtual ICollection<Order> Orders { get; set; }
public virtual ShoppingCart ShoppingCart { get; set; }
public virtual ICollection<AspNetUserClaims> AspNetUserClaims { get; set; }
public virtual ICollection<AspNetRoles> AspNetRoles { get; set; }
}
}
The error occurs when trying to save the addition in the repository. On the _context.SaveChanges() line the method below.
public void CreateBrowsingHistoryEntry(BrowsingHistory bhe)
{
_context.BrowsingHistory.Add(bhe);
_context.SaveChanges();
}
Any help with this issue would be greatly appreciated.
I need to generate a primary key by mask (for example: BS{100-999}-{Rand(100-999)}) But I do not know how to generate a key like this in EF code/ Could somebody help me please to figure this out?
My model:
[Table("Tickets")]
public class Ticket
{
public Ticket()
{
CreationDate = DateTime.UtcNow;
LastChangeDate = DateTime.UtcNow;
UserReviewed = true;
EmailAlert = true;
}
[Key]
[DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; } //now it is Guid But i need this to be string and generated by the above mask
public string UsersName { get; set; }
public string Theme { get; set; }
public string Request { get; set; }
public DateTime CreationDate { get; set; }
public string TypeMask { get; set; }
public string StatusMask { get; set; }
public int SenderId { get; set; }
public bool EmailAlert { get; set; }
public DateTime LastChangeDate { get; set; }
public bool UserReviewed { get; set; }
public virtual ICollection<TicketRecord> Answers { get; set; }
[ForeignKey("StatusMask")]
public virtual TicketStatus Status { get; set; }
[ForeignKey("TypeMask")]
public virtual TicketType Type { get; set; }
[ForeignKey("SenderId")]
public virtual UserProfile Sender { get; set; }
public virtual AttachmentsCollection IncludedFiles { get; set; }
}
EF never generates keys. Either you need to generate the key by yourself or you let the EF know that the key will be generated by the database using StoreGeneragedPattern annotation/setting. EF cannot generate keys as it cannot guarantee uniquenesses for the generated values.
I have a User model object and I wan't to when I get this object to get aspnet_User object with it for additional data (usename etc.)
public class User
{
public Guid UserId_fk { get; set; }
public int UserId { get; set; }
public string FirstName { get; set; }
public virtual AspnetUsers AspnetUsers { get; set; }
}
public class AspnetUsers
{
public Guid ApplicationId { get; set; }
public Guid UserId { get; set; }
public string UserName { get; set; }
public string LoweredUserName { get; set; }
public string MobileAlias { get; set; }
public bool IsAnonymous { get; set; }
public DateTime LastActivityDate { get; set; }
}
In database UserId_fk is FK to aspnet_Users.UserId.
How to map this?