ASP.NET EF Core inserting into multiple tables with foreign key
I really cannot figure this out. I am constantly hitting this error and I am unsure how to modify the code to support 1 to many. The examples I have read up so far are quite difficult to understand. Some suggest modifying fluent API or the model or even the controller.
Error:
SqlException: Cannot insert explicit value for identity column in table 'CompetitionCategory' when IDENTITY_INSERT is set to OFF.
System.Data.SqlClient.SqlCommand+<>c.b__122_0(Task result)
DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
Competition
model class:
public class Competition
{
[Key]
public int ID { get; set; }
[Required]
[Display(Name = "Competition Name")]
public string CompetitionName { get; set; }
[Required]
public string Status { get; set; }
public ICollection<CompetitionCategory> CompetitionCategories { get; set; }
}
CompetitionCategory
model class:
public class CompetitionCategory
{
[Key]
public int ID { get; set; }
[Required]
[Display(Name = "Category Name")]
public string CategoryName { get; set; }
[ForeignKey("CompetitionID")]
public int CompetitionID { get; set; }
}
After some tinkering, I realised to pass the list to the controller I should use a view model as shown here:
public class CategoriesViewModelIEnumerable
{
public Competition competition { get; set; }
public CompetitionCategory competitionCategory { get; set; }
// From Microsoft
public IEnumerable<string> SelectedCategories { get; set; }
public List<SelectListItem> CategoriesList { get; } = new List<SelectListItem>
{
new SelectListItem { Value = "xxx", Text = "xxx" },
new SelectListItem { Value = "yyy", Text = "yyy" },
new SelectListItem { Value = "zzz", Text = "zzz" },
};
}
I can successfully pass the data to my controller and read/print it on the console. However I am hitting the last error which is to save the 2nd category onwards into the database, probably due to some primary key/foreign key restriction.
I can currently only save the first item in the list into the database.
public async Task<IActionResult> Create(CategoriesViewModelIEnumerable model)
{
if (ModelState.IsValid)
{
CompetitionCategory competitionCategory = new CompetitionCategory();
_context.Add(model.competition);
await _context.SaveChangesAsync();
foreach (var CategoryName in model.SelectedCategories)
{
competitionCategory.CategoryName = CategoryName;
competitionCategory.CompetitionID = model.competition.ID;
_context.Add(competitionCategory);
await _context.SaveChangesAsync();
}
await _context.SaveChangesAsync();
}
}
Appreciate your help a lot! :)
c# asp.net-core asp.net-core-mvc ef-core-2.0 ef-core-2.1
add a comment |
I really cannot figure this out. I am constantly hitting this error and I am unsure how to modify the code to support 1 to many. The examples I have read up so far are quite difficult to understand. Some suggest modifying fluent API or the model or even the controller.
Error:
SqlException: Cannot insert explicit value for identity column in table 'CompetitionCategory' when IDENTITY_INSERT is set to OFF.
System.Data.SqlClient.SqlCommand+<>c.b__122_0(Task result)
DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
Competition
model class:
public class Competition
{
[Key]
public int ID { get; set; }
[Required]
[Display(Name = "Competition Name")]
public string CompetitionName { get; set; }
[Required]
public string Status { get; set; }
public ICollection<CompetitionCategory> CompetitionCategories { get; set; }
}
CompetitionCategory
model class:
public class CompetitionCategory
{
[Key]
public int ID { get; set; }
[Required]
[Display(Name = "Category Name")]
public string CategoryName { get; set; }
[ForeignKey("CompetitionID")]
public int CompetitionID { get; set; }
}
After some tinkering, I realised to pass the list to the controller I should use a view model as shown here:
public class CategoriesViewModelIEnumerable
{
public Competition competition { get; set; }
public CompetitionCategory competitionCategory { get; set; }
// From Microsoft
public IEnumerable<string> SelectedCategories { get; set; }
public List<SelectListItem> CategoriesList { get; } = new List<SelectListItem>
{
new SelectListItem { Value = "xxx", Text = "xxx" },
new SelectListItem { Value = "yyy", Text = "yyy" },
new SelectListItem { Value = "zzz", Text = "zzz" },
};
}
I can successfully pass the data to my controller and read/print it on the console. However I am hitting the last error which is to save the 2nd category onwards into the database, probably due to some primary key/foreign key restriction.
I can currently only save the first item in the list into the database.
public async Task<IActionResult> Create(CategoriesViewModelIEnumerable model)
{
if (ModelState.IsValid)
{
CompetitionCategory competitionCategory = new CompetitionCategory();
_context.Add(model.competition);
await _context.SaveChangesAsync();
foreach (var CategoryName in model.SelectedCategories)
{
competitionCategory.CategoryName = CategoryName;
competitionCategory.CompetitionID = model.competition.ID;
_context.Add(competitionCategory);
await _context.SaveChangesAsync();
}
await _context.SaveChangesAsync();
}
}
Appreciate your help a lot! :)
c# asp.net-core asp.net-core-mvc ef-core-2.0 ef-core-2.1
add a comment |
I really cannot figure this out. I am constantly hitting this error and I am unsure how to modify the code to support 1 to many. The examples I have read up so far are quite difficult to understand. Some suggest modifying fluent API or the model or even the controller.
Error:
SqlException: Cannot insert explicit value for identity column in table 'CompetitionCategory' when IDENTITY_INSERT is set to OFF.
System.Data.SqlClient.SqlCommand+<>c.b__122_0(Task result)
DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
Competition
model class:
public class Competition
{
[Key]
public int ID { get; set; }
[Required]
[Display(Name = "Competition Name")]
public string CompetitionName { get; set; }
[Required]
public string Status { get; set; }
public ICollection<CompetitionCategory> CompetitionCategories { get; set; }
}
CompetitionCategory
model class:
public class CompetitionCategory
{
[Key]
public int ID { get; set; }
[Required]
[Display(Name = "Category Name")]
public string CategoryName { get; set; }
[ForeignKey("CompetitionID")]
public int CompetitionID { get; set; }
}
After some tinkering, I realised to pass the list to the controller I should use a view model as shown here:
public class CategoriesViewModelIEnumerable
{
public Competition competition { get; set; }
public CompetitionCategory competitionCategory { get; set; }
// From Microsoft
public IEnumerable<string> SelectedCategories { get; set; }
public List<SelectListItem> CategoriesList { get; } = new List<SelectListItem>
{
new SelectListItem { Value = "xxx", Text = "xxx" },
new SelectListItem { Value = "yyy", Text = "yyy" },
new SelectListItem { Value = "zzz", Text = "zzz" },
};
}
I can successfully pass the data to my controller and read/print it on the console. However I am hitting the last error which is to save the 2nd category onwards into the database, probably due to some primary key/foreign key restriction.
I can currently only save the first item in the list into the database.
public async Task<IActionResult> Create(CategoriesViewModelIEnumerable model)
{
if (ModelState.IsValid)
{
CompetitionCategory competitionCategory = new CompetitionCategory();
_context.Add(model.competition);
await _context.SaveChangesAsync();
foreach (var CategoryName in model.SelectedCategories)
{
competitionCategory.CategoryName = CategoryName;
competitionCategory.CompetitionID = model.competition.ID;
_context.Add(competitionCategory);
await _context.SaveChangesAsync();
}
await _context.SaveChangesAsync();
}
}
Appreciate your help a lot! :)
c# asp.net-core asp.net-core-mvc ef-core-2.0 ef-core-2.1
I really cannot figure this out. I am constantly hitting this error and I am unsure how to modify the code to support 1 to many. The examples I have read up so far are quite difficult to understand. Some suggest modifying fluent API or the model or even the controller.
Error:
SqlException: Cannot insert explicit value for identity column in table 'CompetitionCategory' when IDENTITY_INSERT is set to OFF.
System.Data.SqlClient.SqlCommand+<>c.b__122_0(Task result)
DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
Competition
model class:
public class Competition
{
[Key]
public int ID { get; set; }
[Required]
[Display(Name = "Competition Name")]
public string CompetitionName { get; set; }
[Required]
public string Status { get; set; }
public ICollection<CompetitionCategory> CompetitionCategories { get; set; }
}
CompetitionCategory
model class:
public class CompetitionCategory
{
[Key]
public int ID { get; set; }
[Required]
[Display(Name = "Category Name")]
public string CategoryName { get; set; }
[ForeignKey("CompetitionID")]
public int CompetitionID { get; set; }
}
After some tinkering, I realised to pass the list to the controller I should use a view model as shown here:
public class CategoriesViewModelIEnumerable
{
public Competition competition { get; set; }
public CompetitionCategory competitionCategory { get; set; }
// From Microsoft
public IEnumerable<string> SelectedCategories { get; set; }
public List<SelectListItem> CategoriesList { get; } = new List<SelectListItem>
{
new SelectListItem { Value = "xxx", Text = "xxx" },
new SelectListItem { Value = "yyy", Text = "yyy" },
new SelectListItem { Value = "zzz", Text = "zzz" },
};
}
I can successfully pass the data to my controller and read/print it on the console. However I am hitting the last error which is to save the 2nd category onwards into the database, probably due to some primary key/foreign key restriction.
I can currently only save the first item in the list into the database.
public async Task<IActionResult> Create(CategoriesViewModelIEnumerable model)
{
if (ModelState.IsValid)
{
CompetitionCategory competitionCategory = new CompetitionCategory();
_context.Add(model.competition);
await _context.SaveChangesAsync();
foreach (var CategoryName in model.SelectedCategories)
{
competitionCategory.CategoryName = CategoryName;
competitionCategory.CompetitionID = model.competition.ID;
_context.Add(competitionCategory);
await _context.SaveChangesAsync();
}
await _context.SaveChangesAsync();
}
}
Appreciate your help a lot! :)
c# asp.net-core asp.net-core-mvc ef-core-2.0 ef-core-2.1
c# asp.net-core asp.net-core-mvc ef-core-2.0 ef-core-2.1
edited Dec 30 '18 at 1:00
Tasos K.
6,61552848
6,61552848
asked Dec 29 '18 at 18:26
zzdhxuzzdhxu
90111
90111
add a comment |
add a comment |
4 Answers
4
active
oldest
votes
Well, I potentially see 2 issues.
- You are doing this asynchronously so it is possible that it is trying to save the second database changes before the first ones are completed.
You should be creating the complete model then adding it, the second add in this case should be an update, because you have already added it with the first and saved changes, so it would be better to create your model completely with all of the data and add it and then save changes.
CompetitionCategory competitionCategory = new CompetitionCategory();
foreach (var CategoryName in model.SelectedCategories)
{
competitionCategory.CategoryName = CategoryName;
competitionCategory.CompetitionID = model.competition.ID;
}
_context.Add(model.competition);
await _context.SaveChangesAsync();
Hi sure. Let me try and get back. The async worked when there I added 1 competition and then 1 category. So not too sure if that is the issue
– zzdhxu
Dec 30 '18 at 2:32
I think I will try point 2 first. Will update here again with the results. Thanks for your help! :)
– zzdhxu
Dec 30 '18 at 2:33
using 2 will also fix 1.
– Kelso Sharp
Dec 30 '18 at 5:51
Hi. It didn't work. The error is gone but it doesn't add to the CompetitionCategory table. It only inserts into the Competition table. Thank you
– zzdhxu
Dec 30 '18 at 15:27
1
Well, it was not intended to be used verbatim, just to point you in the right direction :)
– Kelso Sharp
Dec 30 '18 at 16:00
|
show 3 more comments
I believe the issue (haven't actually tested it) is that you're instantiating your CompetitionCategory entity once and then trying to add that single instance to the model for each iteration in the foreach loop.
You should be creating a new CompetitionCategory instance for each iteration and then adding each new entitiy to the model:
foreach (var CategoryName in model.SelectedCategories)
{
CompetitionCategory competitionCategory = new CompetitionCategory();
competitionCategory.CategoryName = CategoryName;
competitionCategory.CompetitionID = model.competition.ID;
_context.Add(competitionCategory);
}
await _context.SaveChangesAsync();
add a comment |
To fix the error, you might consider storing explicit ids into the foreign key, but EF Core sets up a primary key on a table with identity insert set to on. To explicitly turn it off, in your DbContext you can override the method OnModelCreating if you have not already done so and put in this line:
protected override OnModelCreating(DbModelBuilder modelBuilder){
//some more code if necessary - define via Fluent api below
modelBuilder.Entity<CompetitionCategory>().Property(t => t.CompetitionID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
//define also other ids to not have databasegeneration option set to identity to allow explicit idsif required
}
Also you might consider first saving the Competition and CompetitionCategory inside a transaction so you can rollback or commit the transaction if error is encountered or not, using TransactionScope in EF. The error you get anyways is due to you setting in an explicit id and EF default will set up an ID column with identity insert if not explicitly stated so otherwise. You can use the databasegeneratedoption attribute if this is more convenient. See DatabaseGeneratedOption attribute
add a comment |
Edit: This answer works in case it is not clear
Thank you very much to Kelso Sharp for pointing me in the right direction. Fixed it by editing the controller.
For future reference for other users:
Basically you just need to add in your "main model", in this case Competition
.
Since Competition
already have a Collection of CompetitionCategory
, initialize it and add each CompetitionCategory
to the Collection as shown in the for loop.
Lastly, add the model Competition
into the Database. I am assuming EF Core will add the Collection data to the CompetitionCategory
table for you automatically with the foreign key mapping done. (Someone please edit this if it's wrong)
Working Controller:
public async Task<IActionResult> Create(CategoriesViewModelIEnumerable model)
{
if (ModelState.IsValid)
{
model.competition.CompetitionCategories = new Collection<CompetitionCategory>();
foreach (var CategoryName in model.SelectedCategories)
{
model.competition.CompetitionCategories.Add(new CompetitionCategory { CompetitionID=model.competition.ID, CategoryName=CategoryName});
}
_context.Add(model.competition);
await _context.SaveChangesAsync();
}
}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53972251%2fasp-net-ef-core-inserting-into-multiple-tables-with-foreign-key%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
Well, I potentially see 2 issues.
- You are doing this asynchronously so it is possible that it is trying to save the second database changes before the first ones are completed.
You should be creating the complete model then adding it, the second add in this case should be an update, because you have already added it with the first and saved changes, so it would be better to create your model completely with all of the data and add it and then save changes.
CompetitionCategory competitionCategory = new CompetitionCategory();
foreach (var CategoryName in model.SelectedCategories)
{
competitionCategory.CategoryName = CategoryName;
competitionCategory.CompetitionID = model.competition.ID;
}
_context.Add(model.competition);
await _context.SaveChangesAsync();
Hi sure. Let me try and get back. The async worked when there I added 1 competition and then 1 category. So not too sure if that is the issue
– zzdhxu
Dec 30 '18 at 2:32
I think I will try point 2 first. Will update here again with the results. Thanks for your help! :)
– zzdhxu
Dec 30 '18 at 2:33
using 2 will also fix 1.
– Kelso Sharp
Dec 30 '18 at 5:51
Hi. It didn't work. The error is gone but it doesn't add to the CompetitionCategory table. It only inserts into the Competition table. Thank you
– zzdhxu
Dec 30 '18 at 15:27
1
Well, it was not intended to be used verbatim, just to point you in the right direction :)
– Kelso Sharp
Dec 30 '18 at 16:00
|
show 3 more comments
Well, I potentially see 2 issues.
- You are doing this asynchronously so it is possible that it is trying to save the second database changes before the first ones are completed.
You should be creating the complete model then adding it, the second add in this case should be an update, because you have already added it with the first and saved changes, so it would be better to create your model completely with all of the data and add it and then save changes.
CompetitionCategory competitionCategory = new CompetitionCategory();
foreach (var CategoryName in model.SelectedCategories)
{
competitionCategory.CategoryName = CategoryName;
competitionCategory.CompetitionID = model.competition.ID;
}
_context.Add(model.competition);
await _context.SaveChangesAsync();
Hi sure. Let me try and get back. The async worked when there I added 1 competition and then 1 category. So not too sure if that is the issue
– zzdhxu
Dec 30 '18 at 2:32
I think I will try point 2 first. Will update here again with the results. Thanks for your help! :)
– zzdhxu
Dec 30 '18 at 2:33
using 2 will also fix 1.
– Kelso Sharp
Dec 30 '18 at 5:51
Hi. It didn't work. The error is gone but it doesn't add to the CompetitionCategory table. It only inserts into the Competition table. Thank you
– zzdhxu
Dec 30 '18 at 15:27
1
Well, it was not intended to be used verbatim, just to point you in the right direction :)
– Kelso Sharp
Dec 30 '18 at 16:00
|
show 3 more comments
Well, I potentially see 2 issues.
- You are doing this asynchronously so it is possible that it is trying to save the second database changes before the first ones are completed.
You should be creating the complete model then adding it, the second add in this case should be an update, because you have already added it with the first and saved changes, so it would be better to create your model completely with all of the data and add it and then save changes.
CompetitionCategory competitionCategory = new CompetitionCategory();
foreach (var CategoryName in model.SelectedCategories)
{
competitionCategory.CategoryName = CategoryName;
competitionCategory.CompetitionID = model.competition.ID;
}
_context.Add(model.competition);
await _context.SaveChangesAsync();
Well, I potentially see 2 issues.
- You are doing this asynchronously so it is possible that it is trying to save the second database changes before the first ones are completed.
You should be creating the complete model then adding it, the second add in this case should be an update, because you have already added it with the first and saved changes, so it would be better to create your model completely with all of the data and add it and then save changes.
CompetitionCategory competitionCategory = new CompetitionCategory();
foreach (var CategoryName in model.SelectedCategories)
{
competitionCategory.CategoryName = CategoryName;
competitionCategory.CompetitionID = model.competition.ID;
}
_context.Add(model.competition);
await _context.SaveChangesAsync();
answered Dec 29 '18 at 19:56
Kelso SharpKelso Sharp
897510
897510
Hi sure. Let me try and get back. The async worked when there I added 1 competition and then 1 category. So not too sure if that is the issue
– zzdhxu
Dec 30 '18 at 2:32
I think I will try point 2 first. Will update here again with the results. Thanks for your help! :)
– zzdhxu
Dec 30 '18 at 2:33
using 2 will also fix 1.
– Kelso Sharp
Dec 30 '18 at 5:51
Hi. It didn't work. The error is gone but it doesn't add to the CompetitionCategory table. It only inserts into the Competition table. Thank you
– zzdhxu
Dec 30 '18 at 15:27
1
Well, it was not intended to be used verbatim, just to point you in the right direction :)
– Kelso Sharp
Dec 30 '18 at 16:00
|
show 3 more comments
Hi sure. Let me try and get back. The async worked when there I added 1 competition and then 1 category. So not too sure if that is the issue
– zzdhxu
Dec 30 '18 at 2:32
I think I will try point 2 first. Will update here again with the results. Thanks for your help! :)
– zzdhxu
Dec 30 '18 at 2:33
using 2 will also fix 1.
– Kelso Sharp
Dec 30 '18 at 5:51
Hi. It didn't work. The error is gone but it doesn't add to the CompetitionCategory table. It only inserts into the Competition table. Thank you
– zzdhxu
Dec 30 '18 at 15:27
1
Well, it was not intended to be used verbatim, just to point you in the right direction :)
– Kelso Sharp
Dec 30 '18 at 16:00
Hi sure. Let me try and get back. The async worked when there I added 1 competition and then 1 category. So not too sure if that is the issue
– zzdhxu
Dec 30 '18 at 2:32
Hi sure. Let me try and get back. The async worked when there I added 1 competition and then 1 category. So not too sure if that is the issue
– zzdhxu
Dec 30 '18 at 2:32
I think I will try point 2 first. Will update here again with the results. Thanks for your help! :)
– zzdhxu
Dec 30 '18 at 2:33
I think I will try point 2 first. Will update here again with the results. Thanks for your help! :)
– zzdhxu
Dec 30 '18 at 2:33
using 2 will also fix 1.
– Kelso Sharp
Dec 30 '18 at 5:51
using 2 will also fix 1.
– Kelso Sharp
Dec 30 '18 at 5:51
Hi. It didn't work. The error is gone but it doesn't add to the CompetitionCategory table. It only inserts into the Competition table. Thank you
– zzdhxu
Dec 30 '18 at 15:27
Hi. It didn't work. The error is gone but it doesn't add to the CompetitionCategory table. It only inserts into the Competition table. Thank you
– zzdhxu
Dec 30 '18 at 15:27
1
1
Well, it was not intended to be used verbatim, just to point you in the right direction :)
– Kelso Sharp
Dec 30 '18 at 16:00
Well, it was not intended to be used verbatim, just to point you in the right direction :)
– Kelso Sharp
Dec 30 '18 at 16:00
|
show 3 more comments
I believe the issue (haven't actually tested it) is that you're instantiating your CompetitionCategory entity once and then trying to add that single instance to the model for each iteration in the foreach loop.
You should be creating a new CompetitionCategory instance for each iteration and then adding each new entitiy to the model:
foreach (var CategoryName in model.SelectedCategories)
{
CompetitionCategory competitionCategory = new CompetitionCategory();
competitionCategory.CategoryName = CategoryName;
competitionCategory.CompetitionID = model.competition.ID;
_context.Add(competitionCategory);
}
await _context.SaveChangesAsync();
add a comment |
I believe the issue (haven't actually tested it) is that you're instantiating your CompetitionCategory entity once and then trying to add that single instance to the model for each iteration in the foreach loop.
You should be creating a new CompetitionCategory instance for each iteration and then adding each new entitiy to the model:
foreach (var CategoryName in model.SelectedCategories)
{
CompetitionCategory competitionCategory = new CompetitionCategory();
competitionCategory.CategoryName = CategoryName;
competitionCategory.CompetitionID = model.competition.ID;
_context.Add(competitionCategory);
}
await _context.SaveChangesAsync();
add a comment |
I believe the issue (haven't actually tested it) is that you're instantiating your CompetitionCategory entity once and then trying to add that single instance to the model for each iteration in the foreach loop.
You should be creating a new CompetitionCategory instance for each iteration and then adding each new entitiy to the model:
foreach (var CategoryName in model.SelectedCategories)
{
CompetitionCategory competitionCategory = new CompetitionCategory();
competitionCategory.CategoryName = CategoryName;
competitionCategory.CompetitionID = model.competition.ID;
_context.Add(competitionCategory);
}
await _context.SaveChangesAsync();
I believe the issue (haven't actually tested it) is that you're instantiating your CompetitionCategory entity once and then trying to add that single instance to the model for each iteration in the foreach loop.
You should be creating a new CompetitionCategory instance for each iteration and then adding each new entitiy to the model:
foreach (var CategoryName in model.SelectedCategories)
{
CompetitionCategory competitionCategory = new CompetitionCategory();
competitionCategory.CategoryName = CategoryName;
competitionCategory.CompetitionID = model.competition.ID;
_context.Add(competitionCategory);
}
await _context.SaveChangesAsync();
answered Dec 30 '18 at 18:12
devNulldevNull
44636
44636
add a comment |
add a comment |
To fix the error, you might consider storing explicit ids into the foreign key, but EF Core sets up a primary key on a table with identity insert set to on. To explicitly turn it off, in your DbContext you can override the method OnModelCreating if you have not already done so and put in this line:
protected override OnModelCreating(DbModelBuilder modelBuilder){
//some more code if necessary - define via Fluent api below
modelBuilder.Entity<CompetitionCategory>().Property(t => t.CompetitionID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
//define also other ids to not have databasegeneration option set to identity to allow explicit idsif required
}
Also you might consider first saving the Competition and CompetitionCategory inside a transaction so you can rollback or commit the transaction if error is encountered or not, using TransactionScope in EF. The error you get anyways is due to you setting in an explicit id and EF default will set up an ID column with identity insert if not explicitly stated so otherwise. You can use the databasegeneratedoption attribute if this is more convenient. See DatabaseGeneratedOption attribute
add a comment |
To fix the error, you might consider storing explicit ids into the foreign key, but EF Core sets up a primary key on a table with identity insert set to on. To explicitly turn it off, in your DbContext you can override the method OnModelCreating if you have not already done so and put in this line:
protected override OnModelCreating(DbModelBuilder modelBuilder){
//some more code if necessary - define via Fluent api below
modelBuilder.Entity<CompetitionCategory>().Property(t => t.CompetitionID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
//define also other ids to not have databasegeneration option set to identity to allow explicit idsif required
}
Also you might consider first saving the Competition and CompetitionCategory inside a transaction so you can rollback or commit the transaction if error is encountered or not, using TransactionScope in EF. The error you get anyways is due to you setting in an explicit id and EF default will set up an ID column with identity insert if not explicitly stated so otherwise. You can use the databasegeneratedoption attribute if this is more convenient. See DatabaseGeneratedOption attribute
add a comment |
To fix the error, you might consider storing explicit ids into the foreign key, but EF Core sets up a primary key on a table with identity insert set to on. To explicitly turn it off, in your DbContext you can override the method OnModelCreating if you have not already done so and put in this line:
protected override OnModelCreating(DbModelBuilder modelBuilder){
//some more code if necessary - define via Fluent api below
modelBuilder.Entity<CompetitionCategory>().Property(t => t.CompetitionID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
//define also other ids to not have databasegeneration option set to identity to allow explicit idsif required
}
Also you might consider first saving the Competition and CompetitionCategory inside a transaction so you can rollback or commit the transaction if error is encountered or not, using TransactionScope in EF. The error you get anyways is due to you setting in an explicit id and EF default will set up an ID column with identity insert if not explicitly stated so otherwise. You can use the databasegeneratedoption attribute if this is more convenient. See DatabaseGeneratedOption attribute
To fix the error, you might consider storing explicit ids into the foreign key, but EF Core sets up a primary key on a table with identity insert set to on. To explicitly turn it off, in your DbContext you can override the method OnModelCreating if you have not already done so and put in this line:
protected override OnModelCreating(DbModelBuilder modelBuilder){
//some more code if necessary - define via Fluent api below
modelBuilder.Entity<CompetitionCategory>().Property(t => t.CompetitionID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
//define also other ids to not have databasegeneration option set to identity to allow explicit idsif required
}
Also you might consider first saving the Competition and CompetitionCategory inside a transaction so you can rollback or commit the transaction if error is encountered or not, using TransactionScope in EF. The error you get anyways is due to you setting in an explicit id and EF default will set up an ID column with identity insert if not explicitly stated so otherwise. You can use the databasegeneratedoption attribute if this is more convenient. See DatabaseGeneratedOption attribute
answered Dec 30 '18 at 20:59
Tore AurstadTore Aurstad
76958
76958
add a comment |
add a comment |
Edit: This answer works in case it is not clear
Thank you very much to Kelso Sharp for pointing me in the right direction. Fixed it by editing the controller.
For future reference for other users:
Basically you just need to add in your "main model", in this case Competition
.
Since Competition
already have a Collection of CompetitionCategory
, initialize it and add each CompetitionCategory
to the Collection as shown in the for loop.
Lastly, add the model Competition
into the Database. I am assuming EF Core will add the Collection data to the CompetitionCategory
table for you automatically with the foreign key mapping done. (Someone please edit this if it's wrong)
Working Controller:
public async Task<IActionResult> Create(CategoriesViewModelIEnumerable model)
{
if (ModelState.IsValid)
{
model.competition.CompetitionCategories = new Collection<CompetitionCategory>();
foreach (var CategoryName in model.SelectedCategories)
{
model.competition.CompetitionCategories.Add(new CompetitionCategory { CompetitionID=model.competition.ID, CategoryName=CategoryName});
}
_context.Add(model.competition);
await _context.SaveChangesAsync();
}
}
add a comment |
Edit: This answer works in case it is not clear
Thank you very much to Kelso Sharp for pointing me in the right direction. Fixed it by editing the controller.
For future reference for other users:
Basically you just need to add in your "main model", in this case Competition
.
Since Competition
already have a Collection of CompetitionCategory
, initialize it and add each CompetitionCategory
to the Collection as shown in the for loop.
Lastly, add the model Competition
into the Database. I am assuming EF Core will add the Collection data to the CompetitionCategory
table for you automatically with the foreign key mapping done. (Someone please edit this if it's wrong)
Working Controller:
public async Task<IActionResult> Create(CategoriesViewModelIEnumerable model)
{
if (ModelState.IsValid)
{
model.competition.CompetitionCategories = new Collection<CompetitionCategory>();
foreach (var CategoryName in model.SelectedCategories)
{
model.competition.CompetitionCategories.Add(new CompetitionCategory { CompetitionID=model.competition.ID, CategoryName=CategoryName});
}
_context.Add(model.competition);
await _context.SaveChangesAsync();
}
}
add a comment |
Edit: This answer works in case it is not clear
Thank you very much to Kelso Sharp for pointing me in the right direction. Fixed it by editing the controller.
For future reference for other users:
Basically you just need to add in your "main model", in this case Competition
.
Since Competition
already have a Collection of CompetitionCategory
, initialize it and add each CompetitionCategory
to the Collection as shown in the for loop.
Lastly, add the model Competition
into the Database. I am assuming EF Core will add the Collection data to the CompetitionCategory
table for you automatically with the foreign key mapping done. (Someone please edit this if it's wrong)
Working Controller:
public async Task<IActionResult> Create(CategoriesViewModelIEnumerable model)
{
if (ModelState.IsValid)
{
model.competition.CompetitionCategories = new Collection<CompetitionCategory>();
foreach (var CategoryName in model.SelectedCategories)
{
model.competition.CompetitionCategories.Add(new CompetitionCategory { CompetitionID=model.competition.ID, CategoryName=CategoryName});
}
_context.Add(model.competition);
await _context.SaveChangesAsync();
}
}
Edit: This answer works in case it is not clear
Thank you very much to Kelso Sharp for pointing me in the right direction. Fixed it by editing the controller.
For future reference for other users:
Basically you just need to add in your "main model", in this case Competition
.
Since Competition
already have a Collection of CompetitionCategory
, initialize it and add each CompetitionCategory
to the Collection as shown in the for loop.
Lastly, add the model Competition
into the Database. I am assuming EF Core will add the Collection data to the CompetitionCategory
table for you automatically with the foreign key mapping done. (Someone please edit this if it's wrong)
Working Controller:
public async Task<IActionResult> Create(CategoriesViewModelIEnumerable model)
{
if (ModelState.IsValid)
{
model.competition.CompetitionCategories = new Collection<CompetitionCategory>();
foreach (var CategoryName in model.SelectedCategories)
{
model.competition.CompetitionCategories.Add(new CompetitionCategory { CompetitionID=model.competition.ID, CategoryName=CategoryName});
}
_context.Add(model.competition);
await _context.SaveChangesAsync();
}
}
edited Dec 31 '18 at 3:19
answered Dec 30 '18 at 16:10
zzdhxuzzdhxu
90111
90111
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53972251%2fasp-net-ef-core-inserting-into-multiple-tables-with-foreign-key%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown