The property 'Id' is part of the object's key information and cannot be modified after the second insert - entity-framework

I have a table with Id as primary key
The model generated by EF is this
public partial class Home_Orchard_Users_UserPartRecord
{
public int Id { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string NormalizedUserName { get; set; }
public string Password { get; set; }
public string PasswordFormat { get; set; }
public string HashAlgorithm { get; set; }
public string PasswordSalt { get; set; }
public string RegistrationStatus { get; set; }
public string EmailStatus { get; set; }
public string EmailChallengeToken { get; set; }
public Nullable<System.DateTime> CreatedUtc { get; set; }
public Nullable<System.DateTime> LastLoginUtc { get; set; }
public Nullable<System.DateTime> LastLogoutUtc { get; set; }
}
When I tried to insert a data from a list, the first insert was okay but the second one I got error: The property 'Id' is part of the object's key information and cannot be modified.
foreach (var ContentItem in ListContentItem)
{
ContentItemData.Data = ContentItem.Data;
ContentItemData.ContentType_id = 3;
Context.Home_Orchard_Framework_ContentItemRecord.Add(ContentItemData);
Context.SaveChanges();
int Return_Id = ContentItemData.Id;
UserData.Id = Return_Id;
UserData.UserName = ContentItem.UserName;
UserData.Email = ContentItem.Email;
UserData.NormalizedUserName = ContentItem.NormalizedUserName;
UserData.Password = "AMQ6a4CzqeyLbWqrd7EwoaTV23fopf++3FpcBlV+Gsvgja3Ye3LwFlXVHyhAcWyKaw==";
UserData.PasswordFormat = "Hashed";
UserData.HashAlgorithm = "PBKDF2";
UserData.PasswordSalt = "FaED9QsIV9HD95m8FO5OSA==";
UserData.RegistrationStatus = "Approved";
UserData.EmailStatus = "Approved";
UserData.CreatedUtc = DateTime.Today;
Context.Home_Orchard_Users_UserPartRecord.Add(UserData);
//Context.SaveChanges();
i = i + 1;
progress = ((float)i / nCount) * 100;
Console.Write("\r{0}%", progress);
Thread.Sleep(50);
}
Why I can't insert the second time? The Id is the primary key and it's not autogenerated so it has to be input manually.

Related

Entity Framework .Core treating foreign key as a primary key

I have the two classes shown below. When trying to insert two HeroEntry with the same IdentityId, the context is only saving one of the two entries. Any ideas what I am doing wrong?
public class Identity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int IdentityId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
[JsonIgnore]
public virtual HeroEntry HeroEntry { get; set; }
}
public class HeroEntry
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int HeroEntryId { get; set; }
public int IdentityId { get; set; }
public SuperHeroEnum HeroType { get; set; }
public DateTime Startdate { get; set; }
public DateTime EndDate { get; set; }
[ForeignKey("IdentityId")]
public virtual Identity Identity { get; set; }
public virtual List<SuperHeroBreak> SuperHeroBreaks { get; set; }
}
Add code:
var b = new HeroEntry()
{
HeroType = SuperHeroEnum.BATMAN,
Startdate = DateTime.Parse("12/24/2018"),
EndDate = DateTime.Parse("01/04/2019"),
IdentityId = 1,
};
var r = new HeroEntry()
{
HeroType = SuperHeroEnum.ROBIN,
Startdate = DateTime.Parse("12/24/2018"),
EndDate = DateTime.Parse("01/04/2019"),
IdentityId = 1,
};
context.SuperHeroes.AddRange(b, r);
var affected = context.SaveChanges();
Cristian was correct. Adding the navigation property to the identity class solved my issue. Thank you for the help!

How to assign pk values from the controllerp

ArticleIDX is the primary key.
I would like to assign this primary key to Family.
However, the primary key does not seem to be assigned a Family value because the create method is executed and incremented.
What should I do in this case?
[HttpPost]
public ActionResult Create(Articles article)
{
try
{
**article.Family = article.ArticleIDX;**
article.Parent = 0;
article.Depth = 0;
article.Indent = 0;
article.ModifyDate = DateTime.Now;
article.ModifyMemberID = User.Identity.Name;
db.Articles.Add(article);
db.SaveChanges();
}
ViewBag.Result = "OK";
}
catch (Exception ex)
{
Debug.WriteLine("Board");
Debug.WriteLine(ex.ToString());
ViewBag.Result = "FAIL";
}
return View(article);
}
public partial class Articles
{
[Key]
public int ArticleIDX { get; set; }
public int? Family { get; set; }
public int? Depth { get; set; }
public int? Indent { get; set; }
public int? Parent { get; set; }
[StringLength(200)]
public string Title { get; set; }
[Column(TypeName = "text")]
public string Contents { get; set; }
[StringLength(50)]
public string Category { get; set; }
[StringLength(20)]
public string ModifyMemberID { get; set; }
public DateTime? ModifyDate { get; set; }
public virtual Members Members { get; set; }
}
Because, primary key is not generated before inserting. You should insert the row first and assign the generated primary key after.
article.Family = 0;
article.Parent = 0;
article.Depth = 0;
article.Indent = 0;
article.ModifyDate = DateTime.Now;
article.ModifyMemberID = User.Identity.Name;
db.Articles.Add(article);
db.SaveChanges();
article.Family = article.ArticleIDX;//Update the Family after primary key generated
db.SaveChanges();

EF update is inserting and into a different table

I have an MVC 5 website using EF6 code first.
The website will track golf results at events.
Here are my pocos:
public class Event
{
public int EventId { get; set; }
public string VenueName { get; set; }
public string CourseName { get; set; }
public String FirstTeeOff { get; set; }
public DateTime EventDate { get; set; }
public decimal Fee { get; set; }
public virtual ICollection<Result> Results { get; set; }
}
public class Golfer
{
public int GolferId { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }
public int CurrentHandicap { get; set; }
public string Email { get; set; }
public string Telephone { get; set; }
public virtual ICollection<Result> Results { get; set; }
}
public class Result
{
public int ResultId { get; set; }
public Golfer Golfer { get; set; }
public Event Event { get; set; }
public bool Attendance { get; set; }
public int HandicapPlayed { get; set; }
public int ScoreCarded { get; set; }
public int LongestDriveWins { get; set; }
public int NearestPinWins { get; set; }
public Result()
{
Event = new Event();
Golfer = new Golfer();
}
}
The POST edit action for my Result is as follows:
[HttpPost]
[Authorize]
public ActionResult Edit(ResultViewModel resultVM)
{
try
{
DomainClasses.Result resultDomain = _context.Results.Find(resultVM.GolferResults[0].ResultId);
resultDomain.Attendance = resultVM.GolferResults[0].Attendance;
resultDomain.HandicapPlayed = resultVM.GolferResults[0].HandicapPlayed;
resultDomain.ScoreCarded = resultVM.GolferResults[0].ScoreCarded;
resultDomain.LongestDriveWins = resultVM.GolferResults[0].LongestDriveWins;
resultDomain.NearestPinWins = resultVM.GolferResults[0].NearestPinWins;
_context.Results.Attach(resultDomain);
_context.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
I'm getting an error on the SaveChanges. I've used EF Profiler and it showed that it was trying to insert into the Event table:
INSERT [dbo].[Events]
([VenueName],
[CourseName],
[FirstTeeOff],
[EventDate],
[Fee])
VALUES (NULL,
NULL,
NULL,
'0001-01-01T00:00:00' /* #0 */,
0 /* #1 */)
SELECT [EventId]
FROM [dbo].[Events]
WHERE ##ROWCOUNT > 0
AND [EventId] = scope_identity()
Any idead why?
It's most likely because you create instances of the related entities in the Result constructor:
Event = new Event();
Golfer = new Golfer();
Remove those lines from the constructor.

seeding one to many relationship with entity framework

I've looked through quite a few threads about seeding a one to many relationship with EF but can't seem to find the answer to what seems like a simple question. How to do it? I have the following code where I'm trying to create an AuctionItem entity and then add AuctionImage entities to it. But I get a null exception for auctionOne.AuctionImages on the line auctionOne.AuctionImages.Add()... Can anyone tell me what I'm doing wrong? Thanks!
protected override void Seed(AuctionDbContext db)
{
var auctionOne = new AuctionItem()
{
AuctionComplete = string.Empty,
AuctionDate = DateTime.Now.AddDays(-1),
CurrentPrice = 2,
EndPrice = 5,
InitialPrice = 1,
InitialQuantity = 1,
LongDescription = "Long description",
PriceDrops = 2,
QuantityRemaining = 2,
ReserveQuantity = 1,
RetailPrice = 4,
ShortDescription = "Short description",
Title = "Auction one"
};
auctionOne.AuctionImages.Add(new AuctionImage
{
Description = "Beautiful picture",
Filename = "picture.jpg"
});
db.AuctionItems.Add(auctionOne);
base.Seed(db);
}
And here are my classes.
public class AuctionItem
{
[Key]
public int AuctionItemID { get; set; }
[Column(TypeName = "varchar"), MaxLength(256)]
public string Title { get; set; }
public decimal InitialPrice { get; set; }
public int InitialQuantity { get; set; }
public DateTime? AuctionDate { get; set; }
[Column(TypeName = "varchar(max)")]
public string ShortDescription { get; set; }
[Column(TypeName = "varchar(max)")]
public string LongDescription { get; set; }
public decimal RetailPrice { get; set; }
public decimal? EndPrice { get; set; }
public decimal CurrentPrice { get; set; }
public int PriceDrops { get; set; }
public int QuantityRemaining { get; set; }
public int ReserveQuantity { get; set; }
[Column(TypeName = "char"), MaxLength(10)]
public string AuctionComplete { get; set; }
[Column(TypeName = "xml")]
public string Metadata { get; set; }
public virtual ICollection<AuctionImage> AuctionImages { get; set; }
}
public class AuctionImage
{
[Key]
public int AuctionImageID { get; set; }
[ForeignKey("AuctionItem")]
public int AuctionItemID { get; set; }
public virtual AuctionItem AuctionItem { get; set; }
[Column(TypeName = "varchar"), MaxLength(256)]
public string Description { get; set; }
[Column(TypeName = "varchar(max)")]
public string Filename { get; set; }
[Column(TypeName = "xml")]
public string MetaData { get; set; }
}
You haven't allocated the collection for AuctionImages before you are referencing it with the Add, which is why you get the null exception. (When the object is first created, the property will have a null value).
For seeding, it's usually just easiest to do something like:
var auctionOne = new AuctionItem()
{
AuctionComplete = string.Empty,
AuctionDate = DateTime.Now.AddDays(-1),
// ...
AuctionImages = new List<AuctionImage> {
new AuctionImage { Description="", Filename="" },
new AuctionImage { Description="", Filename="" }
}
};
If you want to do it as two separate steps, just allocate the AuctionImages property as a new List<> (or other ICollection) before adding to it:
var auctionOne = new AuctionItem()
{
// ...
Title = "Auction one"
};
auctionOne.AuctionImages = new List<AuctionImage>(); // add this
auctionOne.AuctionImages.Add(new AuctionImage
{
Description = "Beautiful picture",
Filename = "picture.jpg"
});
db.AuctionItems.Add(auctionOne);

EF code first property not mapped

The problem I'm encountering is when I try to insert a new record in a ASPxGridView which is a master of detail in an asp.net page.
This only occurs when adding a new record is required when there is no record.
EnderecoEscola entity:
namespace DAL
{
[Table("CAD_ENDERECO_ESCOLA")]
public class EnderecoEscola
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ENDESC_ID { get; set; }
[Required]
public int ESCOLA_ID { get; set; }
[Association("Escolas", "ESCOLA_ID", "ESCOLA_ID")]
[ForeignKey("ESCOLA_ID")]
public virtual Escola Escola { get; set; }
[Required]
public int TPOEND_ID { get; set; }
[ForeignKey("TPOEND_ID")]
public virtual TipoEndereco TipoEndereco { get; set; }
[Required]
public int ENDESC_UF_ID { get; set; }
[ForeignKey("ENDESC_UF_ID")]
public virtual UnidadeFederativa UnidadeFederativa { get; set; }
[Required]
public int ENDESC_MUN_iD { get; set; }
[ForeignKey("ENDESC_MUN_iD")]
public virtual Municipio Municipio { get; set; }
[StringLength(10), Required]
[MinLength(8)]
public string ENDESC_CEP { get; set; }
[StringLength(100), Required]
[MinLength(10)]
public string ENDESC_ENDERECO { get; set; }
[StringLength(15)]
public string ENDESC_NRO { get; set; }
[StringLength(25)]
public string ENDESC_COMPL { get; set; }
[StringLength(70)]
public string ENDESC_BAIRRO { get; set; }
[NotMapped]
public String TPEND_DESCRICAO { get; set; }
[NotMapped]
public String UF_SIGLA { get; set; }
[NotMapped]
public String MUN_DESCRICAO { get; set; }
}
}
DAL :
namespace DAL.utilities
{
public class OperationCadEnderecoEscola
{
public IQueryable<EnderecoEscola> GetId(int idEsc)
{
using (SecurityCtx ctx = new SecurityCtx())
{
ctx.Configuration.LazyLoadingEnabled = false;
var query = ctx.EnderecoEscola.Include("TipoEndereco").Include("UnidadeFederativa").Include("Municipio").Where(w => w.ESCOLA_ID == idEsc).OrderBy(p => p.ENDESC_ENDERECO).ToList().
Select(w => new EnderecoEscola
{
ENDESC_ID = w.ENDESC_ID,
ESCOLA_ID = w.ESCOLA_ID,
TPOEND_ID = w.TPOEND_ID,
ENDESC_UF_ID = w.ENDESC_UF_ID,
ENDESC_MUN_iD = w.ENDESC_MUN_iD,
ENDESC_CEP = w.ENDESC_CEP,
ENDESC_ENDERECO = w.ENDESC_ENDERECO,
ENDESC_NRO = w.ENDESC_NRO,
ENDESC_COMPL = w.ENDESC_COMPL,
ENDESC_BAIRRO = w.ENDESC_BAIRRO,
TPEND_DESCRICAO = w.TipoEndereco.TPEND_DESCRICAO != null ? w.TipoEndereco.TPEND_DESCRICAO : w.TPEND_DESCRICAO,
UF_SIGLA = w.UnidadeFederativa.UF_SIGLA != null ? w.UnidadeFederativa.UF_SIGLA : w.UF_SIGLA,
MUN_DESCRICAO = w.Municipio.MUN_DESCRICAO != null ? w.Municipio.MUN_DESCRICAO : w.MUN_DESCRICAO
}).Distinct().AsQueryable();
return query;
}
}
}
}
When applying for inclusion in ASPxGridView a new record and the method in DAL public IQueryable <EnderecoEscola> getId (int idEsc) is invoked to retrieve the data and they do not exists it is adding a new record on the master and detail occurs error
A field or property with name 'TPEND_DESCRICAO' was not found in the
selected data source.
Someone could guide me on how to solve the problem.
Tks.