Cannot insert explicit value for identity column while updating entity - entity-framework

I am using ASP.NET Boilerplate template.
I want to update Details table, which contains more than one item. If an item exists, it must update, otherwise a new one must be added and all other entries relating to Master primary key in Details table must be deleted. But it is showing an error:
Cannot insert explicit value for identity column in table
'SemesterDetails' when IDENTITY_INSERT is set to OFF
This is the Master table:
public class StudentDegreeCore : Entity<int>
{
[StringLength(150)]
[Required(ErrorMessage = "Enter Degree College ")]
public string DegreeCollege { get; set; }
[Required()]
public string CollegeID { get; set; }
[StringLength(7, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 7)]
[Required(ErrorMessage = "Enter 10th Pass Year")]
public string CommencementYear { get; set; }
public List<StudentSemesterCore> SemesterDetails { get; set; }
}
This is the Details table, represented by the StudentSemesterCore class:
public class StudentSemesterCore
{
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[StringLength(150)]
[Required(ErrorMessage = "Enter Year/Semester")]
public string YearOrSemester { get; set; }
[Required()]
public virtual int StudentDegreeID { get; set; }
[ForeignKey("StudentDegreeID")]
public virtual StudentDegreeCore StudentDegreeCore { get; set; }
[StringLength(4, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 4)]
[Required(ErrorMessage = "Enter Semester Status")]
public string Status { get; set; }
[DisplayName("% of Marks")]
[RegularExpression(#"\d+(\.\d{1,2})?", ErrorMessage = "Numbers With Two decimal Place Allowed")]
public decimal MarkPercentage { get; set; }
}
This is the Update code:
_studentdegreeRepository.Update(st);
CurrentUnitOfWork.SaveChanges();
It shows an error when SaveChanges is called. Actually, I want to update the details if the same value exists, otherwise add new one and all other data relating to the same StudentDegreeID must be removed.

StudentSemesterCore is not derived from Entity.
You don't need to put Id property in StudentSemesterCore. Remove it.
Add StudentDegreeCoreId to StudentSemesterCore as foreign key reference.

I tried this
public override async Task<StudentDegreeDto> Create(StudentDegreeCreateDto input)
{
//CheckCreatePermission();
StudentDegreeCore st = new StudentDegreeCore();
try
{
StudentDegreeCore core = new StudentDegreeCore()
{
Id = input.Id,
Address1 = input.Address1,
Address2 = input.Address2,
City = input.City,
CollegeID = input.CollegeID,
CommencementYear = input.CommencementYear,
CompletionYear = input.CompletionYear,
CurrentYear = input.CurrentYear,
DegreeCollege = input.DegreeCollege,
DegreeId = input.DegreeId,
OverallPercent = input.OverallPercent,
PinCode = input.PinCode,
PostBox = input.PostBox,
State = input.State,
StreamId = input.StreamId,
UserId = input.UserId
};
core.SemesterDetails = new List<StudentSemesterCore>();
foreach (var items in input.SemesterDetails)
{
core.SemesterDetails.Add(new StudentSemesterCore()
{
GPA = items.GPA,
MarkPercentage = items.MarkPercentage,
Status = items.Status,
UserId = items.UserId ,
Id = items.Id,
StudentDegreeID = items.StudentDegreeID ,
YearOrSemester = items.YearOrSemester,
LastModificationTime = DateTime.Now,
CreationTime = DateTime.Now
});
}
var student = core; //ObjectMapper.Map<StudentDegreeCore>(input);
long uid = (AbpSession.UserId == null) ? 0 : Convert.ToInt64(AbpSession.UserId);
st = _studentRepository.Get(student.Id);
if (st != null && st.Id > 0)
{
st.DegreeCollege = student.DegreeCollege;
st.CollegeID = student.CollegeID;
st.CommencementYear = student.CommencementYear;
st.CompletionYear = student.CompletionYear;
st.LastModificationId = Convert.ToInt32(AbpSession.UserId);
st.LastModificationTime = DateTime.Now;
st.StreamId = student.StreamId;
st.DegreeId = student.DegreeId;
st.CurrentYear = student.CurrentYear;
st.OverallPercent = student.OverallPercent;
st.PinCode = student.PinCode;
st.PostBox = student.PostBox;
st.State = student.State;
st.Address1 = student.Address1;
st.Address2 = student.Address2;
st.City = student.City;
st.SemesterDetails = new List<StudentSemesterCore>();
//st.SemesterDetails = student.SemesterDetails;
_studentRepository.Update(st);
foreach (var items in student.SemesterDetails)
{
_studentSemesterRepository.InsertOrUpdate(items);
}
//_studentRepository.Update(st);
CurrentUnitOfWork.SaveChanges();
}
else
{
student.UserId = Convert.ToInt32(AbpSession.UserId);
student.CreationId = Convert.ToInt32(AbpSession.UserId);
_studentRepository.Insert(student);
CurrentUnitOfWork.SaveChanges();
}
}
catch (Exception ex)
{
}
StudentDegreeDto studentDegreeDto = new StudentDegreeDto()
{
Id = input.Id,
Address1 = input.Address1,
Address2 = input.Address2,
City = input.City,
CollegeID = input.CollegeID,
CommencementYear = input.CommencementYear,
CompletionYear = input.CompletionYear,
CurrentYear = input.CurrentYear,
DegreeCollege = input.DegreeCollege,
DegreeId = input.DegreeId,
OverallPercent = input.OverallPercent,
PinCode = input.PinCode,
PostBox = input.PostBox,
State = input.State,
StreamId = input.StreamId,
UserId = input.UserId
};
studentDegreeDto.SemesterDetails = new List<StudentSemesterDto>();
foreach (var items in input.SemesterDetails)
{
studentDegreeDto.SemesterDetails.Add(new StudentSemesterDto()
{
GPA = items.GPA,
MarkPercentage = items.MarkPercentage,
Status = items.Status,
YearOrSemester = items.YearOrSemester,
LastModificationTime = DateTime.Now,
CreationTime = DateTime.Now
});
}
return studentDegreeDto;
}

Related

List<DateTime> Post call issue

I'm trying to do a JSON post call using a List property (RecurrenceException) but once the AddAppointment() method is called, RecurrenceException will always be null as its supposed to be but I get this exception on my API controller:
Microsoft.Data.SqlClient.SqlException: 'The parameterized query '(#PK int,#Title nvarchar(8),#Description nvarchar(8),#StartDate ' expects the parameter '#RecurrenceException', which was not supplied.'
Below is my client Razor Page code:
async Task AddAppointment(SchedulerCreateEventArgs e)
{
UvwHolidayPlanner holidayPlannerItem = e.Item as UvwHolidayPlanner;
List<DateTime> lst = new List<DateTime>();
holidayPlanner.Pk = holidayPlannerItem.Pk;
holidayPlanner.Title = holidayPlannerItem.Title;
holidayPlanner.Description = holidayPlannerItem.Description;
holidayPlanner.StartDate = holidayPlannerItem.StartDate;
holidayPlanner.EndDate = holidayPlannerItem.EndDate;
holidayPlanner.IsAllDay = holidayPlannerItem.IsAllDay;
if (holidayPlannerItem.RecurrenceRule == null)
{
holidayPlanner.RecurrenceRule = " ";
}
else
{
holidayPlanner.RecurrenceRule = holidayPlannerItem.RecurrenceRule;
}
holidayPlanner.RecurrenceException = holidayPlannerItem.RecurrenceException;
holidayPlanner.RecurrenceId = holidayPlannerItem.RecurrenceId;
await http.CreateClient("ClientSettings").PostAsJsonAsync<UvwHolidayPlanner>($"{_URL}/api/HolidayPlannerOperations/HolidayPlanner", holidayPlanner);
HolidayPlanners = (await http.CreateClient("ClientSettings").GetFromJsonAsync<List<UvwHolidayPlanner>>($"{_URL}/api/lookup/HolidayPlanner"))
.OrderBy(t => t.Title)
.ToList();
StateHasChanged();
}
Below is my class code:
public class UvwHolidayPlanner
{
public string Title { get; set; }
public string Description { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public bool IsAllDay { get; set; }
public int Pk { get; set; }
public string RecurrenceRule { get; set; }
public List<DateTime> RecurrenceException { get; set; }
public int RecurrenceId { get; set; }
}
And below is my API controller code:
[HttpPost]
[Route("HolidayPlanner")]
public void Post([FromBody] UvwHolidayPlanner item)
{
string SQLSTE = "EXEC [dbo].[usp_AddHolidayPlanner] #PK, #Title, #Description, #StartDate, #EndDate, #IsAllDay, #RecurrenceRule, #RecurrenceException, #RecurrenceId";
using (var context = new TestAppContext())
{
List<SqlParameter> param = new List<SqlParameter>
{
new SqlParameter { ParameterName = "#PK", Value = item.Pk },
new SqlParameter { ParameterName = "#Title", Value = item.Title },
new SqlParameter { ParameterName = "#Description", Value = item.Description },
new SqlParameter { ParameterName = "#StartDate", Value = item.StartDate },
new SqlParameter { ParameterName = "#EndDate", Value = item.EndDate },
new SqlParameter { ParameterName = "#IsAllDay", Value = item.IsAllDay },
new SqlParameter { ParameterName = "#RecurrenceRule", Value = item.RecurrenceRule },
new SqlParameter { ParameterName = "#RecurrenceException", Value = item.RecurrenceException },
new SqlParameter { ParameterName = "#RecurrenceId", Value = item.RecurrenceId }
};
context.Database.ExecuteSqlRaw(SQLSTE, param);
}
}

How to convert pSObject to c# class

public class MyInfo
{
public string Status { get; set; }
public string Class { get; set; }
public string FriendlyName { get; set; }
public string InstanceId { get; set; }
}
string strScript = "Get-PnpDevice";
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(strScript);
pipeline.Commands.Add("Out-String");
Collection<PSObject> results = pipeline.Invoke();
runspace.Close();
foreach (PSObject pSObject in results)
{
}
After JsonConvert.SerializeObject(pSObject);
{"CliXml":"<Objs Version=\"1.1.0.1\" xmlns=\"http://schemas.microsoft.com/powershell/2004/04\">\r\n <S>_x000D__x000A_Status Class FriendlyName InstanceId _x000D__x000A_------ ----- ------------ ---------- _x000D__x000A_Unknown HIDClass HID-compliant consumer control device HID\\VID_0..._x000D__x000A_OK System System board ACPI\\PNP0..._x000D__x000A_OK System Motherboard resources ACPI\\PNP0..._x000D__x000A_OK System Motherboard resources SWD\\MSRRA..._x000D__x000A_Unknown HIDClass HID-compliant vendor-defined device HID\\VID_0..._x000D__x000A__x000D__x000A__x000D__x000A_</S>\r\n</Objs>"}
But I need is MyClasss.Class so i can diferentiate or make some condition on it .
1 => Create this classes
public class HardwareDevice
{
public string Name { get; set; }
public List<HardwareProperty> Properties { get; set; }
public HardwareDevice()
{
Properties = new List<HardwareProperty>();
}
}
public class HardwareProperty
{
public string Name { get; set; }
public string Value { get; set; }
}
2 = > Call this method which return List
var hardware = GetHardwareInfo(string "select * from Get-PnpDevice", string scope = "ROOT\\CIMV2")
3 = > here is the method
List<HardwareDevice> GetHardwareInfos(string query, string scope = "ROOT\\CIMV2")
{
List<HardwareDevice> hardwares = new List<HardwareDevice>();
try
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
foreach (ManagementObject share in searcher.Get())
{
HardwareDevice hrd = new HardwareDevice();
try
{
if (share["Name"] != null)
hrd.Name = share["Name"].ToString().Trim();
else
hrd.Name = share.ToString().Trim();
}
catch
{
hrd.Name = share.ToString().Trim();
}
foreach (PropertyData PC in share.Properties)
{
HardwareProperty property = new HardwareProperty();
property.Name = PC.Name;
if (PC.Value != null && PC.Value.ToString() != "")
{
switch (PC.Value.GetType().ToString())
{
case "System.String[]":
string[] str = (string[])PC.Value;
string str2 = "";
foreach (string st in str)
str2 += st + "&";
property.Value = str2.Trim('&');
break;
case "System.UInt16[]":
ushort[] shortData = (ushort[])PC.Value;
string tstr2 = "";
for (int i = 0; i < shortData.Length; i++)
{
tstr2 += shortData[i].ToString() + "&";
}
property.Value = tstr2.Trim('&');
break;
default:
property.Value = PC.Value.ToString().Trim();
break;
}
}
hrd.Properties.Add(property);
}
hardwares.Add(hrd);
}
}
catch (Exception exp)
{
}
return hardwares;
}

Entity Framework Core Select Outer Join

is there an easy way to include a nullable navigation inside a select expression for EF Core?
My model looks like this
public class RootVO
{
[Key]
public int Id { get; set; }
[Required]
[StringLength(200)]
public string Description { get; set; }
public int? RelationId { get; set; }
[ForeignKey(nameof(RelationId))]
public RelationVO Relation { get; set; }
}
public class RelationVO
{
[Key]
public int Id { get; set; }
[Required]
[StringLength(200)]
public string Property1 { get; set; }
[Required]
[StringLength(200)]
public string Property2 { get; set; }
public ICollection<RootVO> RootRelations { get; set; }
}
When I load the data I just want to select certain kind of properties. Currently my expression looks like this:
Expression<Func<RootVO, RootVO>> selectExpr = m => new RootVO
{
Id = m.Id,
Description = m.Description,
Relation = m.Relation != null ? new RelationVO
{
Id = m.Relation.Id,
Property1 = m.Relation.Property1
} : null
};
var result = context.Roots.Select(selectExpr).ToList();
Is there an easier way to handle the relation select?
Edit
Maybe some background here will help:
I have a huge object with a lot of columns and relations, some with inner, some with outer joins. This query gets accessed by a datagrid on UI which can have dynamic columns depending on the user selection. To increase the performance I've written a class that will build the select expression dynamicly depending on the selected columns. For now it is working, but I'm having trouble when an outer join is null due to null-reference excepction.
The debug view on the expression could look like this:
.New IVA.Core.Data.Models.StockMovementLogVO(){
SequenceNo = $m.SequenceNo,
PostingPeriodId = $m.PostingPeriodId,
TransactionDate = $m.TransactionDate,
FinancialYear = $m.FinancialYear,
FinancialYearPeriod = $m.FinancialYearPeriod,
VoucherDate = $m.VoucherDate,
ItemQuantity = $m.ItemQuantity,
BuCode = $m.BuCode,
LocationStructure = .New IVA.Core.Data.Models.LocationStructureVO(){
Id = ($m.LocationStructure).Id,
Description = ($m.LocationStructure).Description
},
BookingType = .New IVA.Core.Data.Models.BookingTypeVO(){
Id = ($m.BookingType).Id,
Description = ($m.BookingType).Description
},
PartnerStockLocationType = .New IVA.Core.Data.Models.StockLocationTypeVO(){
Id = ($m.PartnerStockLocationType).Id,
Description = ($m.PartnerStockLocationType).Description
},
StockLocationType = .New IVA.Core.Data.Models.StockLocationTypeVO(){
Id = ($m.StockLocationType).Id,
Description = ($m.StockLocationType).Description
}
}
StockLocationType and PartnerStockLocationType are outer joins and if those are null the query fails to execute.
I've now changed my expression builder that it will take care of the outer joins by including a null reference check. The expression now looks like this:
.New IVA.Core.Data.Models.StockMovementLogVO(){
SequenceNo = $m.SequenceNo,
PostingPeriodId = $m.PostingPeriodId,
TransactionDate = $m.TransactionDate,
FinancialYear = $m.FinancialYear,
FinancialYearPeriod = $m.FinancialYearPeriod,
VoucherDate = $m.VoucherDate,
ItemQuantity = $m.ItemQuantity,
BuCode = $m.BuCode,
LocationStructure = .New IVA.Core.Data.Models.LocationStructureVO(){
Id = ($m.LocationStructure).Id,
Description = ($m.LocationStructure).Description
},
BookingType = .New IVA.Core.Data.Models.BookingTypeVO(){
Id = ($m.BookingType).Id,
Description = ($m.BookingType).Description
},
PartnerStockLocationType = .If ($m.PartnerStockLocationType != null) {
.New IVA.Core.Data.Models.StockLocationTypeVO(){
Id = ($m.PartnerStockLocationType).Id,
Description = ($m.PartnerStockLocationType).Description
}
} .Else {
null
},
StockLocationType = .If ($m.StockLocationType != null) {
.New IVA.Core.Data.Models.StockLocationTypeVO(){
Id = ($m.StockLocationType).Id,
Description = ($m.StockLocationType).Description
}
} .Else {
null
}
}
Edit
If anyone is interessted how it looks, I've created a repository where I use the class.
https://github.com/NQuirmbach/DynamicQueryBuilder

Insert constraint failed nFOREIGN KEY constraint failed While Seeding Data

I am trying to Seed some sample Data
public class Condition
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Entity
{
public int Id { get; set; }
public string Name { get; set; }
public int ConditionId { get; set; }
public virtual Condition Condition { get; set; }
}
and in my Seed method..
protected override void Seed(AppContext context)
{
Condition condition1 = new Condition();
condition1.Name = "Cond1";
Entity.Entity newEntity1 = new Entity.Entity();
newEntity1.Name = "Test1";
newEntity1.Condition = condition1;
context.Entities.Add(newEntity1);
Condition condition2 = new Condition();
condition2.Name = "Cond2";
Entity.Entity newEntity2 = new Entity.Entity();
newEntity2.Name = "Test Entity 2";
newEntity2.Condition = condition2;
context.Entities.Add(newEntity2);
context.SaveChanges();
}
I am getting this Exception constraint failed FOREIGN KEY constraint failed, I couldn't figure out what wrong I am doing here.
I tried calling context.SaveChanges() after first insertion too and it went fine. but the error appreared only after second context.SaveChanges() only.
protected override void Seed(AppContext context)
{
Condition condition1 = new Condition();
condition1.Id=1;
condition1.Name = "Cond1";
Entity.Entity newEntity1 = new Entity.Entity();
newEntity1.Name = "Test1";
newEntity1.ConditionId=1
newEntity1.Condition = condition1;
context.Entities.Add(newEntity1);
Condition condition2 = new Condition();
condition2.Id=2
condition2.Name = "Cond2";
Entity.Entity newEntity2 = new Entity.Entity();
newEntity2.Name = "Test Entity 2";
newEntity2.ConditionId=2;
newEntity2.Condition = condition2;
context.Entities.Add(newEntity2);
context.SaveChanges();
}
Hope This works..

Why do I get different values from my EntitySet depending on how I LINQ to it?

In debugging the issue in this thread: InvalidCastException when querying nested collection with LINQ I found out that something is wrong with how my Category EntitySet is populated. After selecteding a Category and throwing this exception to see what's going on I get this:
throw new Exception("CID: " + cat.CategoryID +
" LCID: " + cat.LocalizedCategories.First().LocalizedCategoryID +
" CID from LC: " + cat.LocalizedCategories.First().Category.CategoryID);
CID: 352 LCID: 352 CID from LC: 191
What am I doing wrong that causes CategoryID to have different values depending on how I LINQ to it? It should be 191, and not the same value as the LocalizedCategoryID.
This is the code I use to get the Category:
int categoryId = 352; // In reality this comes from a parameter and is supposed
// to be 191 to get the Category.
var cat = categoriesRepository.Categories.First(c => c.CategoryID == categoryId);
This is my domain object with some unrelated stuff stripped:
[Table(Name = "products")]
public class Product
{
[HiddenInput(DisplayValue = false)]
[Column(Name = "id", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]
public int ProductID { get; set; }
[Required(ErrorMessage = "Please enter a product name")]
[Column]
public string Name { get; set; }
[Required(ErrorMessage = "Please enter a description")]
[DataType(DataType.MultilineText)]
[Column(Name = "info")]
public string Description { get; set; }
private EntitySet<Category> _Categories = new EntitySet<Category>();
[System.Data.Linq.Mapping.Association(Storage = "_Categories", OtherKey = "CategoryID")]
public ICollection<Category> Categories
{
get { return _Categories; }
set { _Categories.Assign(value); }
}
}
[Table(Name = "products_types")]
public class Category
{
[HiddenInput(DisplayValue = false)]
[Column(Name = "id", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]
public int CategoryID { get; set; }
public string NameByCountryId(int countryId)
{
return _LocalizedCategories.Single(lc => lc.CountryID == countryId).Name;
}
private EntitySet<LocalizedCategory> _LocalizedCategories = new EntitySet<LocalizedCategory>();
[System.Data.Linq.Mapping.Association(Storage = "_LocalizedCategories", OtherKey = "LocalizedCategoryID")]
public ICollection<LocalizedCategory> LocalizedCategories
{
get { return _LocalizedCategories; }
set { _LocalizedCategories.Assign(value); }
}
private EntitySet<Product> _Products = new EntitySet<Product>();
[System.Data.Linq.Mapping.Association(Storage = "_Products", OtherKey = "ProductID")]
public ICollection<Product> Products
{
get { return _Products; }
set { _Products.Assign(value); }
}
}
[Table(Name = "products_types_localized")]
public class LocalizedCategory
{
[HiddenInput(DisplayValue = false)]
[Column(Name = "id", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]
public int LocalizedCategoryID { get; set; }
[Column(Name = "products_types_id")]
private int CategoryID;
private EntityRef<Category> _Category = new EntityRef<Category>();
[System.Data.Linq.Mapping.Association(Storage = "_Category", ThisKey = "CategoryID")]
public Category Category
{
get { return _Category.Entity; }
set { _Category.Entity = value; }
}
[Column(Name = "country_id")]
public int CountryID { get; set; }
[Column]
public string Name { get; set; }
}
This (in class Category) looks weird:
[System.Data.Linq.Mapping.Association(Storage = "_LocalizedCategories",
OtherKey = "LocalizedCategoryID" )] // ????
public ICollection<LocalizedCategory> LocalizedCategories
Category has a collection of LocalizedCategorys, which means that in the database the table products_types_localized has a foreign keyCategoryID. That field should be the "OtherKey". How was this mapping generated?