Year/Month based Post Archive List With Entity Framework - sql

I want to make a simple Blog Post Archive List like below
2014
January (1)
2013
December (1)
November (14) -> Link to search with date
October (3)
May (5)
April (3)
I need to send this via ViewBag.Archives. When I perform below SQL in SQL Server Management Studio.
select year(Created) as PostYear, datename(month,Created) as PostMonth,count(ID) as ArticleAmount from Post group by year(Created), datename(MONTH,Created) order by PostYear, PostMonth
I get:
PostYear PostMonth ArticleAmount
2010 February 1
2011 September 1
2012 April 1
2012 February 1
2013 February 4
2013 March 1
2014 February 1
My Code:
ViewBag.Archives = db.Posts
.GroupBy(group => new { group.Created.Year, group.Created.Month })
.Select(x => new { count = x.Count(), Year = x.Key.Year, Month = x.Key.Month });
My View:
#foreach (var item in ViewBag.Archives)
{
<p>#item.Year</p>
}
ERROR: Additional information: 'object' does not contain a definition for 'Year'
Thank you

Are you looking for something like:
ViewBag.Archives = db.Posts
.GroupBy(group => new {group.Created.Year, group.Created.Month})
.Take(5)
.Select(x => new GuestBookPost()
{
count = x.Count,
Year = x.Key.Created.Year,
Month = x.Key.Created.Month
}).ToList();
EDIT
Use the ToList() on the select :).
Try using an object or a model to store the data in, this will also make is easier to add month names as accessing in the view. Example below, replaced "ObjectName()", with "PostGroup":
public class GuestbookPost {
public int Count { get; set; }
public int Year { get; set; }
public int Month { get; set; }
}
PS: Sorry for the bad formatting, still learning :)

Related

Entity Framework Core wrong format date in database but read correct

I'm working on my project with ASP.NET Core 3.1 and Entity Framework Core. I have a table with a column of Date datatype:
[Column(TypeName = "Date")]
[Required]
public DateTime Date { get; set; }
Recently when I insert data in this table, date is inserted like below:
It is marvelous that when I read data from this table to show in calendar plugin, date is correct format:
This is my code for save data in database:
var dtDate = Convert.ToDateTime(date);
_db.ImPossibleReserveDates.Add(new ImPossibleReserveDate
{
Date = dtDate.Date,
InsertTime = DateTime.Now,
IsRemoved = false
});
And this code for read data:
var list = _db.ImPossibleReserveDates.Where(x => !x.IsRemoved).Select(x => new
{
date = x.Date.ToString("yyyy-MM-dd"),
TITLE = "تعطیل"
});
No matter in server or local!
Why did this happen?
check your converted date in server before save it
its seem two convert in your date

select, group, sum with ASP LINQ + private compare method

i am working on an ASP MVC Project and i have a part where i need to export some data to an excel file. the thing is that i need to sum some rows to display a single row. I am not familiar with sql or linq and i am struggling to get the result i want.
there should be 4 columns: requester(string), date(datetime), collection(string), timeinvested(int).
the grouping should be by the column 'collection' (string) as default and if the filter input for requester or date was filled than that would be the next level of grouping. the column 'timespent' should be summarized by the result of the grouping.
example:
requester, date, collection, timeinvested
(1) john, jan 1st, 2019, collection1, 1
(2) mike, jan 1st, 2019, collection1, 3
(3) eric, jan 1st, 2019, collection1, 2
(4) july, jan 1st, 2019, collection2, 5
(5) john, jan 1st, 2012, collection1, 3
here we have 5 rows from the table, once we filter to export only by default (column collection) then rows 1+2+3+5 should sum to 1 row and the 2nd row will be row 4, because the collections are different. like so:
requester, date, collection, timeinvested
(1) john, jan 1st, 2019, collection1, 9
(2) july, jan 1st, 2019, collection2, 5
if i choose to filter also by requester or date then it should apply accordingly.
one big thing here is that there is a private method that checks the date to a particular date and it should export to the file the date year if its after or before the checked date. for example: relative date dec 1st of the same year
if the row date is before relative date then we should write date year - 1;
thanks
var q = (from a in items
select new {
Requester = a.Requester.Name,
Collection = a.Collection.Name,
TimeSpent = a.TimeSpent,
Year = a.Date,
})
.ToList()
.GroupBy(x => new {
x.Requester,
x.Collection,
x.Year,
x.TimeSpent
})
.Select(y => new CollectionModel {
Requester = y.Key.Requester,
Collection = y.Key.Collection,
TimeSpent = y.Sum(z => Convert.ToInt32(z.TimeSpent)),
Year = checkDate(y.Key.Year),
});
return q.ToList();
this is how i made it work:
var q = (from a in items
select new {
Requester = a.Requester.Name,
Collection = a.Collection.Name,
TimeSpent = a.TimeSpent,
Year = a.Date,
})
.Where(Where(a => dt == null || (dt != null && a.Year == dt.Year))
.ToList()
.GroupBy(x => new {
x.Requester,
x.Collection,
x.Year,
})
.Select(y => new CollectionModel {
Requester = y.Key.Requester,
Collection = y.Key.Collection,
TimeSpent = y.Sum(z => Convert.ToInt32(z.TimeSpent)),
Year = checkDate(y.Key.Year),
});
return q.ToList();
First, remove the "x.TimeSpent" from your GroupBy, you need to aggregate that variable, not group by it. secondly, could you post the output as well?

Using automapper.collection in aspnet core & ef core doesn't updated edited records in a collection

I'm using asnet boilerplaite aspnet core and ef core. I've initialized automapper.collection in PreInitialize as follows:
Configuration.Modules.AbpAutoMapper().Configurators.Add(
cfg =>{
cfg.AddCollectionMappers();
cfg.CreateMap<OrderDTO, Order>().EqualityComparison((odto, o) => odto.ID == o.ID);
cfg.CreateMap<OrderItemDTO, OrderItem>().EqualityComparison((odto, o) => odto.ID == o.ID);
}
);
I'm using ObjectMapper.Map(odto, o); to map between the dto and entity, but what I find are new orderitem in the orderitems collection within orders save fine, but any edits to existing entries seem to not update to the db.
The order entity and collection are loaded from the repository using the following:
var #item = await _orderRepository.GetAll().Include(x => x.Items).Include(x => x.Items).ThenInclude(x => x.Product).AsNoTracking().FirstOrDefaultAsync(x => x.Id == id);
here is the Update method:
public override async Task<OrderDto> Update(OrderDto input)
{
var ord = await _orderManager.GetA(input.Id);
ObjectMapper.Map(input, ord);
CheckErrors(await _orderManager.UpdateA(ord));
return MapToEntityDto(await _orderManager.GetA(input.Id));
}
The values of input and ord variables are as follows when trying to update the orderitem record:
input {OrderDto}
Code "1" string
Id 1 int
Items Count = 1 System.Collections.Generic.ICollection<OrderItemDto>
- [0] {OrderItemDto}
Id 1 int
OrderId 1 int
+ Product {ProductLoadDto}
ProductId 4 int
Quantity 22 double
MovementDate {28-Jul-18 2:36:41 AM} System.DateTime
ord {[Order 1]} Order
Code "1" string
Id 1 int
Items Count = 1 System.Collections.Generic.ICollection<OrderItem>
- [0] {OrderItem 1}
Id 1 int
OrderId 1 int
+ Product {[Product 4]} Venues.Products.Product
ProductId 4 int
Quantity 1 double
MovementDate {28-Jul-18 12:06:41 PM} System.DateTime
Is there something I'm missing to get automapper.collection to handle the collection edits automatically ?
Have you tried the Entity Framework Core repo?
https://github.com/AutoMapper/AutoMapper.Collection.EFCore/tree/development
I used the extension listed here to resolve the issue:
https://entityframeworkcore.com/knowledge-base/39452054/asp-net-core-with-ef-core---dto-collection-mapping

Group By Sum Linq to SQL in C#

Really stuck with Linq to SQL grouping and summing, have searched everywhere but I don't understand enough to apply other solutions to my own.
I have a view in my database called view_ProjectTimeSummary, this has the following fields:
string_UserDescription
string_ProjectDescription
datetime_Date
double_Hours
I have a method which accepts a to and from date parameter and first creates this List<>:
List<view_UserTimeSummary> view_UserTimeSummaryToReturn =
(from linqtable_UserTimeSummaryView
in datacontext_UserTimeSummary.GetTable<view_UserTimeSummary>()
where linqtable_UserTimeSummaryView.datetime_Week <= datetime_To
&& linqtable_UserTimeSummaryView.datetime_Week >= datetime_From
select linqtable_UserTimeSummaryView).ToList<view_UserTimeSummary>();
Before returning the List (to be used as a datasource for a datagridview) I filter the string_UserDescription field using a parameter of the same name:
if (string_UserDescription != "")
{
view_UserTimeSummaryToReturn =
(from c in view_UserTimeSummaryToReturn
where c.string_UserDescription == string_UserDescription
select c).ToList<view_UserTimeSummary>();
}
return view_UserTimeSummaryToReturn;
How do I manipulate the resulting List<> to show the sum of the field double_Hours for that user and project between the to and from date parameters (and not separate entries for each date)?
e.g. a List<> with the following fields:
string_UserDescription
string_ProjectDescription
double_SumOfHoursBetweenToAndFromDate
Am I right that this would mean I would have to return a different type of List<> (since it has less fields than the view_UserTimeSummary)?
I have read that to get the sum it's something like 'group / by / into b' but don't understand how this syntax works from looking at other solutions... Can someone please help me?
Thanks
Steve
Start out by defining a class to hold the result:
public class GroupedRow
{
public string UserDescription {get;set;}
public string ProjectDescription {get;set;}
public double SumOfHoursBetweenToAndFromDate {get;set;}
}
Since you've already applied filtering, the only thing left to do is group.
List<GroupedRow> result =
(
from row in source
group row by new { row.UserDescription, row.ProjectDescription } into g
select new GroupedRow()
{
UserDescription = g.Key.UserDescription,
ProjectDescription = g.Key.ProjectDescription,
SumOfHoursBetweenToAndFromDate = g.Sum(x => x.Hours)
}
).ToList();
(or the other syntax)
List<GroupedRow> result = source
.GroupBy(row => new {row.UserDescription, row.ProjectDescription })
.Select(g => new GroupedRow()
{
UserDescription = g.Key.UserDescription,
ProjectDescription = g.Key.ProjectDescription,
SumOfHoursBetweenToAndFromDate = g.Sum(x => x.Hours)
})
.ToList();

Yii min date validation rule

How can I add a minimum date validation rule in a Model?
Example:
I have a column dt_ini as DATE, which I need to restrict the input as D+7, on create.
If today is: october 1st, 2012
the minimum valid date on create would be: october 8th, 2012.
Otherwise, I would throw a validation error as: Your date must be at least 7 days from now.
The code I would expect is something like this: (this is NOT tested, and probably won't work)
public function rules(){
return array('dt_ini', 'date', 'minDate' => '+7'),
}
Thanks.
Is this what you are looking for?
Create custom valid rule as follows:
class YourModel extends CActiveModel
{
// some....
public function rules(){
return array('dt_ini', 'dateValid', 'minDate' => '+7 day', 'on' => 'create');
}
public function dateValid($attribute, $params)
{
$valid=null;
$today = date('Y-m-d', time());
if(isset($params['minDate']))
$valid = date('Y-m-d', strtotime($params['minDate'])); //+7 day
if( !is_null($valid) )
{ //for increamental date
if($this->dt_ini > $valid || $this->dt_ini < $today )
$this->addError($attribute, 'enter error message');
}
}
}