Linq: Count value of multiple column - entity-framework

I have a table like below:
Now I want a result like
In a single query how is it possible to prepare an entity like below?
public BurndownJiraIssue(
DateTime date,
int toDoCount,
int inProgressCount)

You can GroupBy Date to get the required reuslt
var result = list.GroupBy(x => x.Date).Select(x => new BurndownJiraIssue
{
Date = x.Key,
ToDoCount = x.ToList().Count(c => c.Status == "In Progress"),
InProgressCount = x.ToList().Count(c => c.Status == "Done"),
});

You can try with this overload of .GroupBy:
class Program
{
static void Main(string[] args)
{
List<StatusDTO> statuses = new List<StatusDTO>
{
new StatusDTO
{
Id = 1,
Date = "8-Apr",
Status = "In Progress"
},
new StatusDTO
{
Id = 2,
Date = "8-Apr",
Status = "In Progress"
},
new StatusDTO
{
Id = 3,
Date = "8-Apr",
Status = "In Progress"
},
new StatusDTO
{
Id = 4,
Date = "8-Apr",
Status = "Done"
},
new StatusDTO
{
Id = 5,
Date = "9-Apr",
Status = "In Progress"
},
new StatusDTO
{
Id = 6,
Date = "9-Apr",
Status = "Done"
},
new StatusDTO
{
Id = 7,
Date = "9-Apr",
Status = "Done"
}
};
List<ResultStatusDTO> results = statuses.GroupBy(x => x.Date, x => x, (a, b) => new ResultStatusDTO
{
Date = a,
DoneCount = b.Count(x => x.Status == "Done"),
InProgressCount = b.Count(x => x.Status == "In Progress")
}).ToList();
}
}
public class ResultStatusDTO
{
public string Date { get; set; }
public int InProgressCount { get; set; }
public int DoneCount { get; set; }
}
public class StatusDTO
{
public int Id { get; set; }
public string Date { get; set; }
public string Status { get; set; }
}

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 serialize entities that have a one to many relationship and a pagination in entity framework?

I have a two Model for two table having foreign key relationship. I have to get record from both table in single request.
The structure of model is as follows:-
EmployeeRecord.cs
public partial class EmployeeRecord
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public tblEmployeeRecord()
{
this.countries = new HashSet<tblCountry>();
}
public int EmployeeId { get; set; }
public string Name { get; set; }
public string userName { get; set; }
public string userRole { get; set; }
public string id { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Country> countries { get; set; }
}
2.Country.cs
public partial class Country
{
public int CountryId { get; set; }
public int EmployeeId { get; set; }
public string CountryName { get; set; }
public virtual EmployeeRecord employeeRecord { get; set; }
}
EmployeeController.cs
public class EmployeeRecordsController : ApiController
{
private EstorageEntitiesforCombineView db = new EstorageEntitiesforCombineView();
// GET: api/EmployeeRecords
public IEnumerable<EmployeeRecord> GetEmployeeRecords([FromUri]PagingParameterModel pagingparametermodel)
{
var source= db.EmployeeRecords.OrderBy(a => a.EmployeeId);
// Get's No of Rows Count
if (pagingparametermodel.userRole == "HR")
{
source= (from a in db.EmployeeRecords
where a.userRole == "HR"
select a).OrderBy(a => a.EmployeeId);
}
else if(pagingparametermodel.userRole == "eStorage Admin")
{
source = (from a in db.EmployeeRecords
where a.userRole == "eStorage Admin"
select a).OrderBy(a => a.EmployeeId);
} else if(pagingparametermodel.userRole == "SharedService")
{
source = (from a in db.EmployeeRecords
where a.userRole == "SharedService"
select a).OrderBy(a => a.EmployeeId);
}
if(pagingparametermodel.toSearch == 1 && pagingparametermodel.userRole == "ALL")
{
source = (from b in db.EmployeeRecords
where b.Name.StartsWith(pagingparametermodel.name)
select b).OrderBy(a => a.EmployeeId);
}else if (pagingparametermodel.toSearch==1) {
source= (from b in db.EmployeeRecords
where b.Name.StartsWith(pagingparametermodel.name) && b.userRole==pagingparametermodel.userRole
select b).OrderBy(a => a.EmployeeId);
}
int count = source.Count();
// Parameter is passed from Query string if it is null then it default Value will be pageNumber:1
int CurrentPage = pagingparametermodel.pageNumber;
// Parameter is passed from Query string if it is null then it default Value will be pageSize:20
int PageSize = pagingparametermodel.pageSize;
// Display TotalCount to Records to User
int TotalCount = count;
// Calculating Totalpage by Dividing (No of Records / Pagesize)
int TotalPages = (int)Math.Ceiling(count / (double)PageSize);
// Returns List of Customer after applying Paging
var items = source.Skip((CurrentPage - 1) * PageSize).Take(PageSize).ToList();
// if CurrentPage is greater than 1 means it has previousPage
var previousPage = CurrentPage > 1 ? "Yes" : "No";
// if TotalPages is greater than CurrentPage means it has nextPage
var nextPage = CurrentPage < TotalPages ? "Yes" : "No";
// Object which we are going to send in header
var paginationMetadata = new
{
totalCount = TotalCount,
pageSize = PageSize,
currentPage = CurrentPage,
totalPages = TotalPages,
previousPage,
nextPage
};
// Setting Header
System.Web.HttpContext.Current.Response.Headers.Add("Paging-Headers", Newtonsoft.Json.JsonConvert.SerializeObject(paginationMetadata));
// Returing List of Customers Collections
return items;
}
}
I want the response as follows :-
[{
"tblCountries": [
{
"CountryId": 265,
"EmployeeId": 350,
"CountryName": "INWEST"
}
],
"EmployeeId": 350,
"Name": "ABC",
"userName": "abc#mail.com",
"userRole": "HR",
"id": nbh546652n45
}]
But the response is as follows:-
[{
"tblCountries": [],
"EmployeeId": 350,
"Name": "ABC",
"userName": "abc#mail.com",
"userRole": "HR",
"id": nbh546652n45
}]
I have also tried, Include(a => a.countries) as follows:-
source= (from a in db.EmployeeRecords
where a.userRole == "HR"
select a).Include(a => a.countries).OrderBy(a => a.EmployeeId);
But i am getting following error:-
<ExceptionMessage>
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'.
</ExceptionMessage>
<ExceptionType>System.InvalidOperationException</ExceptionType>
<StackTrace/>
<InnerException>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Object graph for type 'System.Collections.Generic.HashSet`1[[eStorageApi.Models.tblCountry, eStorageApi, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' contains cycles and cannot be serialized if reference tracking is disabled.
</ExceptionMessage>
<ExceptionType>
System.Runtime.Serialization.SerializationException
</ExceptionType>
Tried including these LOCs into webApiConfig.cs:-
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling= Newtonsoft.Json.ReferenceLoopHandling.Ignore;
config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None;
Still getting the same error.
Project your domain model into something else before returning it from your api. This better controls the response data format and if a property gets added (such as ssn) it doesn't get inadvertently exposed. This also has the added benefit of fixing your cyclical references.
return items.Select(i => new {
i.Name,
i.Username,
...
Countries = i.Countries.Select(c => new {
c.CountryId,
c.CountryName,
...
}
};
You need to do the relationship between employeeRecord and countries. Try with this:
source= db.EmployeeRecords.Include(e => e.countries).Select(c => c.employeeRecord)
.Where(a => a.userRole == "HR");
And when you do the request you need specify text: Application/Json

Cannot insert explicit value for identity column while updating entity

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;
}

Entity Framework Migrations seeds duplicate rows

I've got two classes
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Item
{
public int Id { get; set; }
public sting Name { get; set; }
public Category Category { get; set; }
}
I have EF Migrations and the following seed:
var instockCategory = new Category() { Name = "InStock" };
var outofStockCategory = new Category() { Name = "OutOfStock" };
context.Items.AddOrUpdate(
d => d.Name,
new Item() { Name = "Item1", Category = instockCategory },
new Item() { Name = "Item2", Category = outofStockCategory },
new Item() { Name = "Item3", Category = outofStockCategory }
);
The line "d => d.Name" makes sure that based on the name of the item, there won't be duplicate records when I reseed the database.
However, the first time I execute this, two categories are created with id 1 and 2. But the second time I run this, 3 new categories are created!
Can I fix this without manually adding every single category first?
You have to use AddOrUpdate for your categories too.
var instockCategory = default(Category);
var outofStockCategory = default(Category);
context.Set<Category>().AddOrUpdate(
c => c.Name,
instockCategory = new Category() { Name = "InStock" },
outofStockCategory = new Category() { Name = "OutOfStock" }
);
context.Items.AddOrUpdate(
d => d.Name,
new Item() { Name = "Item1", Category = instockCategory },
new Item() { Name = "Item2", Category = outofStockCategory },
new Item() { Name = "Item3", Category = outofStockCategory }
);
An explicit DbSet on your Context class is not necessary.
public class Context : DbContext
{
public DbSet<Item> Items { get; set; }
}

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?