.NET Foreign Key Cannot be Inserted - c#

I have used foreign keys many times before and set up these models just the same however I'm getting this error, the error also occurs when writing usertableID:
A foreign key value cannot be inserted because a corresponding primary key value does not exist. [ Foreign key constraint name = FK_dbo.Outreaches_dbo.OutreachNames_OutreachNamesID ]
Can anyone explain?
Code causing error:
foreach (var item in records)
{
List<string> foundEmails = EmailScraper.Main(item.domain);
string[] emails = foundEmails.ToArray();
var outreach = new Outreach {
domain = item.domain,
email1 = foundEmails.ElementAtOrDefault(0),
email2 = foundEmails.ElementAtOrDefault(1),
email3 = foundEmails.ElementAtOrDefault(2),
email4 = foundEmails.ElementAtOrDefault(3),
email5 = foundEmails.ElementAtOrDefault(4),
email6 = foundEmails.ElementAtOrDefault(5),
UserTableID = UserTableID,
OutreachNamesID = listNumber
};
db.OutreachLists.Add(outreach);
db.SaveChanges();
}
var outreachlist = new OutreachNames
{
ID = listNumber,
listName = model.listName,
listCount = count,
listSent = 0,
unread = 0,
replyRate = 0,
UserTableID = UserTableID,
};
db.OutreachNames.Add(outreachlist);
db.SaveChanges();
Model Outreach:
namespace Linkofy.Models
{
public class Outreach
{
public int ID { get; set; }
public int? OutreachNamesID { get; set; }
public virtual OutreachNames OutreachNames { get; set; }
public string name { get; set; }
[Required]
public string domain { get; set; }
public string email1 { get; set; }
public string email2 { get; set; }
public string email3 { get; set; }
public string email4 { get; set; }
public string email5 { get; set; }
public string email6 { get; set; }
public string email7 { get; set; }
public string email8 { get; set; }
public int? UserTableID { get; set; }
public virtual UserTable UserTable { get; set; }
}
}
Model OutreachNames:
namespace Linkofy.Models
{
public class OutreachNames
{
public int ID { get; set; }
[Required]
public string listName { get; set; }
public int listCount { get; set; }
public int listSent { get; set; }
public int unread { get; set; }
public int replyRate { get; set; }
public virtual ICollection<Outreach> OutreachLists { get; set; }
public int? UserTableID { get; set; }
public virtual UserTable UserTable { get; set; }
}
}

When saving your Outreach you are setting the FK OutreachNamesID to an ID of a record which doesn't exist yet. You need to create this record first or use Entity Framework to create OutreachNames as a child entity. Both entities need to be persisted to the db in one transaction.
You can create the child entity inside of the parent and persist them in one go like this:
var outreach = new Outreach
{
OutreachNames = new OutreachNames
{
...
}
}
db.OutreachLists.Add(outreach);
db.SaveChanges();

Related

EF Code first, table relationship problem

I get an error in the comments model in relations, I'm waiting for a practical answer, it seems like there is nothing difficult. I use the picture model easily in the article model. I thought of using this table in the auhor model, but I am stuck in relationships, what should I do?
public class Article
{
public int Id { get; set; }
public string Title { get; set; } = string.Empty;
public string Detail { get; set; } = string.Empty;
public DateTime CreatedAt { get; set; }
public DateTime? UpdatedAt { get; set; }
public bool IsActive { get; set; } = false;
// Scaler properties
public int AuthorId { get; set; }
public int CategoryId { get; set; }
// Navigation properties
public virtual Picture Picture { get; set; } = new Picture();
public virtual Author Author { get; set; } = new Author();
public virtual Category Category { get; set; } = new Category();
public virtual ICollection<Comment>? Comments { get; set; }
}
public class Author
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Surname { get; set; } = string.Empty;
public string EMail { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public DateTime DateOfBirth { get; set; }
public DateTime CreatedAt { get; set; }
// Navigation properties
public virtual ICollection<Article>? Articles { get; set; }
public virtual ICollection<Comment>? Comments { get; set; }
}
public class Category
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public byte SortBy { get; set; }
// Navigation property
public virtual ICollection<Article>? Articles { get; set; }
}
public class Comment
{
public int Id { get; set; }
public string Content { get; set; } = string.Empty;
public DateTime CreatedAt { get; set; }
public bool IsActive { get; set; } = false;
// Scaler properties
public int ArticleId { get; set; }
public int AuthorId { get; set; }
// Navigation properties
public virtual Article Article { get; set; } = new Article();
public virtual Author Author { get; set; } = new Author();
}
public class Picture
{
public int Id { get; set; }
public string Src { get; set; } = string.Empty;
public string Alt { get; set; } = string.Empty;
public string? Title { get; set; }
// Scaler property
public int ArticleId { get; set; }
// Navigation property
public virtual Article Article { get; set; } = new Article();
}
This is the error:
Introducing FOREIGN KEY constraint 'FK_Comments_Authors_AuthorId' on
table 'Comments' 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
Are there any problems in other relationships? we can discuss

"Cannot insert the value NULL into column" despite value not being NULL

I'm using Entity Framework to populate a an SQL database table. My object 'WebcpdActivity' has a property 'OwnerIdDsc' that is an int. This gets populated (along with all the other properties) with a value shortly before being saved to the database:
WebcpdActivity.OwnerIdDsc = 0;
webContext.CPDActivities.Add(WebcpdActivity);
webContext.SaveChanges();
At the point of SaveChanges I get an error:
Cannot insert the value NULL into column 'OwnerIdDsc', table 'CPDActivityRecord.dbo.CPDActivity'; column does not allow nulls. INSERT fails. The statement has been terminated.
When I step through the code at the point of SaveChanges the WebcpdActivity.OwnerIdDsc property is indeed '0' and not 'NULL'.
EDIT 1*: (edited again to add correct version)
'CPDActivity' class which 'WebcpdActivity' is an instance of
public partial class CPDActivity
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public CPDActivity()
{
this.CPDActivityExtendeds = new HashSet<CPDActivityExtended>();
}
public string ModifiedByName { get; set; }
public string ModifiedByYomiName { get; set; }
public string sb_cqmoduleidName { get; set; }
public string sb_eventdateidName { get; set; }
public string sb_MemberContactIdYomiName { get; set; }
public string sb_MemberContactIdName { get; set; }
public string CreatedOnBehalfByName { get; set; }
public string CreatedOnBehalfByYomiName { get; set; }
public string ModifiedOnBehalfByName { get; set; }
public string ModifiedOnBehalfByYomiName { get; set; }
public string CreatedByName { get; set; }
public string CreatedByYomiName { get; set; }
public System.Guid OwnerId { get; set; }
public string OwnerIdName { get; set; }
public string OwnerIdYomiName { get; set; }
public int OwnerIdDsc { get; set; }
public Nullable<int> OwnerIdType { get; set; }
public Nullable<System.Guid> OwningUser { get; set; }
public Nullable<System.Guid> OwningTeam { get; set; }
public System.Guid sb_cpdactivityId { get; set; }
public Nullable<System.DateTime> CreatedOn { get; set; }
public Nullable<System.Guid> CreatedBy { get; set; }
public Nullable<System.DateTime> ModifiedOn { get; set; }
public Nullable<System.Guid> ModifiedBy { get; set; }
public Nullable<System.Guid> CreatedOnBehalfBy { get; set; }
public Nullable<System.Guid> ModifiedOnBehalfBy { get; set; }
public Nullable<System.Guid> OwningBusinessUnit { get; set; }
public int statecode { get; set; }
public Nullable<int> statuscode { get; set; }
public byte[] VersionNumber { get; set; }
public Nullable<int> ImportSequenceNumber { get; set; }
public Nullable<System.DateTime> OverriddenCreatedOn { get; set; }
public Nullable<int> TimeZoneRuleVersionNumber { get; set; }
public Nullable<int> UTCConversionTimeZoneCode { get; set; }
public string sb_name { get; set; }
public Nullable<System.DateTime> sb_ActivityDate { get; set; }
public Nullable<bool> sb_confirmedbysupervisor { get; set; }
public Nullable<decimal> sb_CPDHours { get; set; }
public Nullable<decimal> sb_CPDPoints { get; set; }
public string sb_FutureDevelopment { get; set; }
public Nullable<System.DateTime> sb_FutureDevelopmentTargetDate { get; set; }
public string sb_ReflectedOutcome { get; set; }
public Nullable<int> sb_StructuredCPD { get; set; }
public Nullable<int> sb_type { get; set; }
public Nullable<int> sb_UnstructuredCPD { get; set; }
public Nullable<System.Guid> sb_MemberContactId { get; set; }
public Nullable<System.Guid> sb_cqmoduleid { get; set; }
public Nullable<System.Guid> sb_eventdateid { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<CPDActivityExtended> CPDActivityExtendeds { get; set; }
public static explicit operator CPDActivity(sb_cpdactivity v)
{
CPDActivity sb_cpda = new CPDActivity();
sb_cpda.ModifiedByName = v.ModifiedByName;
sb_cpda.ModifiedByYomiName = v.ModifiedByYomiName;
sb_cpda.sb_cqmoduleidName = v.sb_cqmoduleidName;
sb_cpda.sb_eventdateidName = v.sb_eventdateidName;
sb_cpda.sb_MemberContactIdYomiName = v.sb_MemberContactIdYomiName;
sb_cpda.sb_MemberContactIdName = v.sb_MemberContactIdName;
sb_cpda.CreatedOnBehalfByName = v.CreatedOnBehalfByName;
sb_cpda.CreatedOnBehalfByYomiName = v.CreatedOnBehalfByYomiName;
sb_cpda.ModifiedOnBehalfByName = v.ModifiedOnBehalfByName;
sb_cpda.ModifiedOnBehalfByYomiName = v.ModifiedOnBehalfByYomiName;
sb_cpda.CreatedByName = v.CreatedByName;
sb_cpda.CreatedByYomiName = v.CreatedByYomiName;
sb_cpda.OwnerId = v.OwnerId;
sb_cpda.OwnerIdName = v.OwnerIdName;
sb_cpda.OwnerIdYomiName = v.OwnerIdYomiName;
sb_cpda.OwnerIdDsc = v.OwnerIdDsc;
sb_cpda.OwnerIdType = v.OwnerIdType;
sb_cpda.OwningUser = v.OwningUser;
sb_cpda.OwningTeam = v.OwningTeam;
sb_cpda.sb_cpdactivityId = v.sb_cpdactivityId;
sb_cpda.CreatedOn = v.CreatedOn;
sb_cpda.CreatedBy = v.CreatedBy;
sb_cpda.ModifiedOn = v.ModifiedOn;
sb_cpda.ModifiedBy = v.ModifiedBy;
sb_cpda.CreatedOnBehalfBy = v.CreatedOnBehalfBy;
sb_cpda.ModifiedOnBehalfBy = v.ModifiedOnBehalfBy;
sb_cpda.OwningBusinessUnit = v.OwningBusinessUnit;
sb_cpda.statecode = v.statecode;
sb_cpda.statuscode = v.statuscode;
sb_cpda.VersionNumber = v.VersionNumber;
sb_cpda.ImportSequenceNumber = v.ImportSequenceNumber;
sb_cpda.CreatedOn = v.CreatedOn;
sb_cpda.TimeZoneRuleVersionNumber = v.TimeZoneRuleVersionNumber;
sb_cpda.UTCConversionTimeZoneCode = v.UTCConversionTimeZoneCode;
sb_cpda.sb_name = v.sb_name;
sb_cpda.sb_ActivityDate = v.sb_ActivityDate;
sb_cpda.sb_confirmedbysupervisor = v.sb_confirmedbysupervisor;
sb_cpda.sb_CPDHours = v.sb_CPDHours;
sb_cpda.sb_CPDPoints = v.sb_CPDPoints;
sb_cpda.sb_FutureDevelopment = v.sb_FutureDevelopment;
sb_cpda.sb_FutureDevelopmentTargetDate = v.sb_FutureDevelopmentTargetDate;
sb_cpda.sb_ReflectedOutcome = v.sb_ReflectedOutcome;
sb_cpda.sb_StructuredCPD = v.sb_StructuredCPD;
sb_cpda.sb_type = v.sb_type;
sb_cpda.sb_UnstructuredCPD = v.sb_UnstructuredCPD;
sb_cpda.sb_MemberContactId = v.sb_MemberContactId;
sb_cpda.sb_cqmoduleid = v.sb_cqmoduleid;
sb_cpda.sb_eventdateid = v.sb_eventdateid;
return sb_cpda;
}
}
EDIT 2
added whole of Using block
using (CPDWebContext webContext = new CPDWebContext())
{
Guid activityId = Guid.NewGuid();
sb_cpdactivity blankSb_cpdactivity = new sb_cpdactivity();
blankSb_cpdactivity = getCPDData.populateActivtyMetaData(blankSb_cpdactivity);
CPDActivity WebcpdActivity = new CPDActivity();
WebcpdActivity = (CPDActivity)blankSb_cpdactivity;
WebcpdActivity.sb_cpdactivityId = activityId;
WebcpdActivity.CreatedOn = DateTime.Now;
WebcpdActivity.ModifiedOn = DateTime.Now;
WebcpdActivity.statecode = 0;
WebcpdActivity.statuscode = 1;
WebcpdActivity.sb_MemberContactId = bsavaMember.MemberID;
decimal minutes = decimal.Parse(ddl_minutes.SelectedValue);
WebcpdActivity.sb_CPDHours = decimal.Parse(tb_hours.Text) + minutes;
WebcpdActivity.sb_name = tb_title.Text;
WebcpdActivity.sb_ActivityDate = Convert.ToDateTime(DateTime.ParseExact(tb_date.Text, "dd-MM-yyyy", CultureInfo.InvariantCulture));
lbl_notification.Text = bsavaMember.UserName + ",\r\n" + bsavaMember.MemberNumber + ",\r\n" + bsavaMember.MemberID + ",\r\n" + WebcpdActivity.sb_ActivityDate.ToString();
CPDActivityExtended cpdActivityExtended = new CPDActivityExtended();
cpdActivityExtended.SubjectArea = tb_area.Text;
cpdActivityExtended.Notes = tb_notes.Text;
cpdActivityExtended.Location = tb_location.Text;
cpdActivityExtended.Username = bsavaMember.UserName;
cpdActivityExtended.MemberNumber = bsavaMember.MemberNumber;
cpdActivityExtended.ContactId = bsavaMember.MemberID;
cpdActivityExtended.CPDActivityId = activityId;
cpdActivityExtended.id = Guid.NewGuid();
cpdActivityExtended.ActiveRecord = 1;
// testing
int test = WebcpdActivity.OwnerIdDsc;
WebcpdActivity.OwnerIdDsc = 1;
//
webContext.CPDActivities.Add(WebcpdActivity); // error triggered here
webContext.CPDActivityExtendeds.Add(cpdActivityExtended);
try
{
webContext.SaveChanges();
}
catch (Exception exc)
{
string error = exc.Message.ToString();
}
}
EDIT 3
I tried to keep the code to the areas I though relevant but it seems this issue may be a little more involved than originally thought. Basically; we have a Microsoft CRM installation that has a table we needed to replicate and only update the replicated table and extend with a further table. This table was replicated without any key constraints but with the data types and data constraints. So basically Table A (sb_cpdactivity) in Database A has been replicated as Table B (CPDActivity) in Database B and I have added Table C (CPDActivityExtended) to Database B.
The idea being we read from the original but NOT save to it. So when we save or create a new record we only do it to the NEW table (Table B,C Database B) Hence there is a way of converting between the original and the duplicate, if needs be).
Table B and C are standalone tables in their own database. Table C has a foreign key that is the primary key of Table B. The webContext only connects to this one database.
Hope this makes sense.
Okay, this took a while and it turns out this error was caused by the edmx file not actually having a mapping to the column that was referenced in the error. So when entity framework passed the object over to the database, that column (and several others) were not included and the database was unable to add a row where a non-nullable column was expecting a value.
I updated the edmx file so that ALL of the columns mapped correctly and everything is now fine.
I think you can't insert a NULL value because you did not declare your int? OwnerIdDsc variable as being NULLABLE.
Go back to the class properties and see exactly how you declared it.

Entity Framework Null Foreign Keys on Seed

I'm trying to figure out what is going on here. When I seed my database, my foreign key that it generates is always null. My model is simple:
public class PnlTarget
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int PnlTargetId { get; set; }
public ReferenceAsset Underlyer { get; set; }
public decimal Target { get; set; }
public virtual PnlSettings PnlSettings { get; set; }
}
public class PnlSettings
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public int PnlSettingsId { get; set; }
public ColloquialType Type { get; set; }
public virtual PnlTarget SPTSX60 { get; set; }
public virtual PnlTarget SPTXLVPR { get; set; }
public virtual PnlTarget STBANKX { get; set; }
public virtual PnlTarget SX5E { get; set; }
public virtual PnlTarget RTY { get; set; }
public virtual PnlTarget SPX { get; set; }
[DataType(DataType.DateTime)]
public DateTime LastEdited { get; set; }
public string LastEditedBy { get; set; }
}
So it's a 1..0 to many relationship. When I seed it with something like this:
PnlSettings vanillaAccelerator = new PnlSettings
{
PnlSettingsId = 1,
Type = ColloquialType.VanillaAccelerator,
RTY = new PnlTarget {Underlyer = ReferenceAsset.RTY, Target = (decimal) 0.004},
SPX = new PnlTarget {Underlyer = ReferenceAsset.SPX, Target = (decimal) 0.004},
SPTSX60 = new PnlTarget { Underlyer = ReferenceAsset.SPTSX60, Target = (decimal)0.004},
SPTXLVPR = new PnlTarget { Underlyer = ReferenceAsset.SPTXLVPR, Target = (decimal)0.004},
STBANKX = new PnlTarget { Underlyer = ReferenceAsset.STBANKX, Target = (decimal)0.004},
SX5E = new PnlTarget { Underlyer = ReferenceAsset.SX5E, Target = (decimal)0.004},
LastEdited = DateTime.Now,
LastEditedBy = "SEED"
};
My foreign key property is always null as illustrated here. I've tried implementing a foreign key property manually using the [ForeignKey] annotation but unfortunately it still generates this null column. Is this intended?
Thanks!

one to zero or one Entityframework navigation property null

I have an context with one to zero or one relationship in entity Framework.
but when i load my entity it will not load the related entity. It allways be null.
Here is my classes:
public class Timerow
{
[Key]
public int Id { get; set; }
[Required]
public int BestNo { get; set; }
[Required]
public int PosNo { get; set; }
[Required]
public int EmpNo { get; set; }
public virtual TimerowOvertime TimerowOvertimes { get; set; }
}
public class TimerowOvertime
{
[Key]
[ForeignKey("Timerow")]
public int Id { get; set; }
[Required]
public float Hours { get; set; }
public DateTime? Transfered { get; set; }
public bool Weekend { get; set; }
public bool ATF { get; set; }
[Required]
public virtual Timerow Timerow { get; set; }
}
But when i try to select Timerow and the related timerowOvertimes, timerowOvertimes allways be null.
i try this:
var timeRows = db.Timerows.ToList();
foreach (var timeRow in timeRows)
{
TimeSheet modelRow = new TimeSheet
{
Id = timeRow.Id,
Date = timeRow.Date,
BestNo = timeRow.BestNo,
PosNo = timeRow.PosNo,
Comment = timeRow.Comment,
Hours = timeRow.Hours,
Ready = timeRow.Ready,
SkillsNoId = timeRow.SkillsNoId
};
if(timeRow.TimerowOvertimes == null)
{
modelRow.ATF = false;
modelRow.Weekend = false;
modelRow.Overtime = 0;
}
else
{
modelRow.Overtime = timeRow.TimerowOvertimes.Hours;
modelRow.ATF = timeRow.TimerowOvertimes.ATF;
modelRow.Weekend = timeRow.TimerowOvertimes.Weekend;
}
}
Anyone has any idea about this?
You shouldn't have the Id property in TimerowOvertime annotated both as [Key] and [ForeignKey]. Currently it looks to bind the Timerow by using the primary key of TimerowOvertime entity. So you need to extend the TimerowOverTime entity to contain TimerowId property and annotate it with the [ForeignKey] attribute.
[ForeignKey("Timerow")]
public int TimerowId { get; set; }

How to add foreign key to entity

An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception.
I'm using EF Code first and I'm getting error above when I trying do this:
public ActionResult CreateTransaction(TransactionViewModel model)
{
try
{
if (model.MemberId != 0 && model.SubcategoryId != 0 & model.CategoryId != 0)
{
Transaction t = new Transaction();
t.Amount = model.Amount;
t.Comment = model.Comment;
t.Date = DateTime.Now;
t.TransactionSubcategory = db.Subcategories.Find(model.SubcategoryId);//and i have error in this line
//i tried also this code below but it's the same error
//db.Subcategories.Find(model.SubcategoryId).Transactions.Add(t);
db.Members.Find(model.MemberId).Transactions.Add(t);
db.SaveChanges();
return RedirectToAction("Index");
}
else
{
return RedirectToAction("CreateTransaction") ;
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
return RedirectToAction("CreateTransaction");
}
}
And there is my model
public class Subcategory
{
public Subcategory()
{
IsGlobal = false;
Transactions = new List<Transaction>();
}
public int Id { get; set; }
public string Name { get; set; }
public TransactionType TypeOfTransaction { get; set; }
public Category OwnerCategory { get; set; }
public List<Transaction> Transactions { get; set; }
public bool IsGlobal { get; set; }
}
public class Transaction
{
public int Id { get; set; }
public Decimal Amount { get; set; }
public DateTime Date { get; set; }
public string Comment { get; set; }
public Subcategory TransactionSubcategory { get; set; }
public Member OwnerMember { get; set; }
}
I don't know why thats happen because in database in Transaction table i see there is column with FK.
If you need there is rest of the model
public class Budget
{
public Budget()
{
Members = new List<Member>();
}
public int Id { get; set; }
public string BudgetName { get; set; }
public string OwnerName { get; set; }
public DateTime CreatedTime { get; set; }
public List<Member> Members { get; set; }
}
public class Category
{
public Category()
{
IsGlobal = false;
}
public int Id { get; set; }
public string Name { get; set; }
public List<Subcategory> Subcategories { get; set; }
public Budget OwnerBudget { get; set; }
public bool IsGlobal { get; set; }
}
public class Member
{
public Member()
{
Transactions = new List<Transaction>();
}
public Budget OwnerBudget { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public DateTime CreatedTime { get; set; }
public List<Transaction> Transactions { get; set; }
}
public enum TransactionType
{
Income,
Expenditure
}
Try adding
public int TransactionSubcategoryId { get; set; }
public int OwnerMemberId { get; set; }
In your Transaction class.

Categories