Convert BSON Document string property to Datetime object - c#

I stored data on Mongo db as below document
public class BookingDocument{
public string Id {get;set;}
public List<ActivityDocument> Activities {get;set;}
public string Status {get;set;}
}
public class ActivityDocument {
public string DateFrom {get;set;}
public string Status {get;set;}
}
I have to filter BookingList Collection with the requested date pass from user
public async Task<List<BookingDocument>> ActivityBookingList(string start,string end)
{
DateTime startDate;
DateTime endDate;
startDate = DateTime.ParseExact(start + " " + "00:00:00", "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
endDate = DateTime.ParseExact(end + " " + "00:00:00", "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
**solution 1**
var filter = new BsonDocument("$expr", new BsonDocument(
"$and", new BsonArray{
new BsonDocument("$gte",new BsonArray{
new BsonDocument("$dateFromString","$Activities.DateFrom"), startDate.ToString("yyyy-MM-dd")
}),
new BsonDocument("$lte",new BsonArray{
new BsonDocument("$dateFromString","$Activities.DateFrom"), endDate.ToString("yyyy-MM-dd")
})
}
));
totalCount = await BookingCollection
.Find(Builders<BookingDocument>.Filter.And(filter))
.CountDocumentsAsync();
}
returns
$dateFromString only supports an object as an argument, found: string
error
I tried below options as well
Solution 2
var filter = new BsonDocument("$expr", new BsonDocument(
"$and", new BsonArray{
new BsonDocument("$gte",new BsonArray{
new BsonDocument("$toDate","$Activities.DateFrom"),startDate
}),
new BsonDocument("$lte",new BsonArray{
new BsonDocument("$toDate","$Activities.DateFrom"),endDate
})
}
));
totalCount = await BookingCollection
.Find(Builders<BookingDocument>.Filter.And(filter))
.CountDocumentsAsync();
}
return
Unsupported conversion from array to date in $convert with no onError
value
error
but below is return the output but it only checks first element in the activity list
var filter = new BsonDocument("$expr", new BsonDocument(
"$and", new BsonArray{
new BsonDocument("$gte",new BsonArray{
new BsonDocument("$dateFromString",new BsonDocument("dateString", new BsonDocument("$arrayElemAt", new BsonArray { "$Activities.DateFrom", 0 }))),startDate
}),
new BsonDocument("$lte",new BsonArray{
new BsonDocument("$dateFromString",new BsonDocument("dateString", new BsonDocument("$arrayElemAt", new BsonArray { "$Activities.DateFrom", 0 }))),endDate
})
}
));
totalCount = await BookingCollection
.Find(Builders<BookingDocument>.Filter.And(filter))
.CountDocumentsAsync();
please help to sort out this issue

Related

c# using Google.Apis.Calendar.v3 create meeting for next month every weekday 30 min event

I want to create daily weekdays event for 30 minit. it seems there is something wrong in
Recurrence = new String[] { "RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;UNTIL=" + nextmonthlastdayString + "T040000Z" },
I am not able to find solution tried many things.
public async Task<ActionResult> NewEvent()
{
var credential = await GetCredentialForApiAsync();
var initializer = new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "ASP.NET MVC5 Calendar Sample",
};
var service = new CalendarService(initializer);
var today = DateTime.Now;
var nextmonth = today.AddMonths(1).AddDays(-today.Day + 1);
var nextmonthString = nextmonth.ToString("yyyyMMdd");
var nxtmonthLastDate= DateTime.DaysInMonth(nextmonth.Year, nextmonth.Month);
DateTime lastDayNextMonth = nextmonth.AddDays(-nextmonth.Day + nxtmonthLastDate);
var nextmonthlastdayString = lastDayNextMonth.ToString("yyyyMMdd");
var lastDayofMonthString = DateTime.DaysInMonth(nextmonth.Year, nextmonth.Month).ToString(nextmonth.Year + "" + nextmonth.Month + "" + nextmonth.Day);
DateTime start = DateTime.Now;
DateTime end = start + TimeSpan.FromMinutes(30);
//start = DateTime.SpecifyKind(start, DateTimeKind.Local);
//end = DateTime.SpecifyKind(end, DateTimeKind.Local);
Event newEvent = new Event()
{
Summary = " Dealer Meeting",
Location = "1600 Amphitheatre Parkway., Mountain View, CA 94043",
Description = "A chance to learn more about Google APIs.",
Start = new EventDateTime()
{
DateTime = nextmonth,
TimeZone = "Asia/Kolkata",
},
End = new EventDateTime()
{
DateTime = lastDayNextMonth,
TimeZone = "Asia/Kolkata",
},
//Recurrence = new String[] { "RRULE:FREQ=DAILY;COUNT=5" },
//Recurrence = new String[] { "RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR;UNTIL="+ nextmonth + "T040000Z" },
Recurrence = new String[] { "RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;UNTIL=" + nextmonthlastdayString + "T040000Z" },
Attendees = new EventAttendee[] {
new EventAttendee() { Email = "test#test.com" },
},
Reminders = new Event.RemindersData()
{
UseDefault = false,
Overrides = new EventReminder[] {
new EventReminder() { Method = "email", Minutes = 24 * 60 },
new EventReminder() { Method = "sms", Minutes = 10 },
}
}
};
String calendarId = "primary";
EventsResource.InsertRequest request = service.Events.Insert(newEvent, calendarId);
Event createdEvent = request.Execute();
return View();
}
Your RRULE is correct, the problem is theend date
As per documentation:
end
The (exclusive) end time of the event. For a recurring event, this is the end time of the first instance.
This means that you should modify
{
DateTime = lastDayNextMonth,
TimeZone = "Asia/Kolkata",
}
to
End = new EventDateTime()
{
DateTime = start + TimeSpan.FromMinutes(30),
TimeZone = "Asia/Kolkata",
}
Sample:
Start = new EventDateTime()
{
DateTime = "2021-11-01T09:00:00",
TimeZone = "Asia/Kolkata",
}
End = new EventDateTime()
{
DateTime = "2021-11-01T09:30:00",
TimeZone = "Asia/Kolkata",
}

AWS SDK .NET DynamoDB ASYNC

I am trying to use AWS SDK for .NET Core.
Create a table to count views on videos.
Add a view count for a day.
Increment existing count for a day.
Query for video counts between two dates for a video.
.NET Core AWS SDK uses Async methods which are not documented in AWS. There is a feature request on their github page for this to happen.... but it is dated from last year. (https://github.com/aws/aws-sdk-net/issues/787)
CREATE THE TABLE
This works and creates a table on the AWS Console.
var ctRequest = new CreateTableRequest
{
AttributeDefinitions = new List<AttributeDefinition>()
{
new AttributeDefinition
{
AttributeName = "ViewUid",
AttributeType = ScalarAttributeType.S
},
new AttributeDefinition
{
AttributeName = "ViewDate",
AttributeType = ScalarAttributeType.S
}
},
KeySchema = new List<KeySchemaElement>
{
new KeySchemaElement
{
AttributeName = "ViewUid",
KeyType = KeyType.HASH //Partition key
},
new KeySchemaElement
{
AttributeName = "ViewDate",
KeyType = KeyType.RANGE
}
},
ProvisionedThroughput = new ProvisionedThroughput
{
ReadCapacityUnits = 5,
WriteCapacityUnits = 6
},
TableName = _settings.AWSDynamoDBViewCountTable
};
var response = _client.CreateTableAsync(ctRequest).Result;
UPDATE AND ITEM WITH AUTO-INCREMENT A FIELD
This, sadly, is where i hit issues. The old docs are found here under the Atomic Counter section. (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LowLevelDotNetItemCRUD.html)
Invalid ConditionExpression: Syntax error; token: \"SET\", near: \"SET
VC\"
var viewData = new Document();
viewData["ViewUid"] = videoUid; //Table entry UID
viewData["VideoId"] = videoId; // Video ID
viewData["ViewDate"] = date;
viewData["ViewCount"] = 0;
//Document result = await _viewCountTable.PutItemAsync(viewData);
Expression expr = new Expression();
expr.ExpressionStatement = "SET #VC = #VC + :val";
expr.ExpressionAttributeValues[":val"] = 1;
expr.ExpressionAttributeNames["#VC"] = "ViewCount";
var updateConfig = new UpdateItemOperationConfig() {
ConditionalExpression = expr,
ReturnValues = ReturnValues.UpdatedNewAttributes
};
var result = await _viewCountTable.UpdateItemAsync(viewData, updateConfig);
return result;
QUERY FOR DATE RANGE
Get one video's view count for a date range.
string queryTimeSpanStartString = dateFrom.ToString(AWSSDKUtils.ISO8601DateFormat);
string queryTimeSpanEndString = dateTo.ToString(AWSSDKUtils.ISO8601DateFormat);
var request = new QueryRequest
{
TableName = _settings.AWSDynamoDBViewCountTable,
KeyConditions = new Dictionary<string, Condition>()
{
{
"VideoId", new Condition()
{
ComparisonOperator = "EQ",
AttributeValueList = new List<AttributeValue>()
{
new AttributeValue { S = videoId }
}
}
},
{
"ViewDate",
new Condition
{
ComparisonOperator = "BETWEEN",
AttributeValueList = new List<AttributeValue>()
{
new AttributeValue { S = queryTimeSpanStartString },
new AttributeValue { S = queryTimeSpanEndString }
}
}
}
}
};
var response = await _client.QueryAsync(request);
Any help would be appreciated.
I was able to update the ViewCount with the following code:
string tableName = "videos";
var request = new UpdateItemRequest
{
Key = new Dictionary<string, AttributeValue>() { { "ViewUid", new AttributeValue { S = "replaceVideoIdhere" } } },
ExpressionAttributeNames = new Dictionary<string, string>()
{
{"#Q", "ViewCount"}
},
ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
{
{":incr", new AttributeValue {N = "1"}}
},
UpdateExpression = "SET #Q = #Q + :incr",
TableName = tableName
};
var response = await _dynamoDbClient.UpdateItemAsync(request);
I created a table called "videos" with a partition key named "ViewUid" as string. Let me know if this works for you.

How to include null vlaues while sorting using linq

I am having 2 reports and combining them into a list. some of the item has null values.when i do sorting, it moves null values at the last.
Here is the sample program
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<Report> reports = new List<Report>();
Report[] report1 = {
new Report{Id=10001,Date=null},
new Report{Id=10001,Date=null},
new Report{Id=10001,Date=Convert.ToDateTime("01/01/2017")}};
Report[] report2 = {
new Report{Id=10002,Date=null},
new Report{Id=10002,Date=null},
new Report{Id=10002,Date=Convert.ToDateTime("03/01/2017")}};
Report[] report3 = {
new Report{Id=10003,Date=null},
new Report{Id=10003,Date=null},
new Report{Id=10003,Date=Convert.ToDateTime("05/01/2017")}};
Report[] report4 = {
new Report{Id=10004,Date=null},
new Report{Id=10004,Date=null},
new Report{Id=10004,Date=Convert.ToDateTime("07/01/2017")}};
reports.AddRange(report1);
reports.AddRange(report2);
reports.AddRange(report3);
reports.AddRange(report4);
var report5 = new List<Report>()
{
new Report{Id=null,Date=Convert.ToDateTime("02/01/2017")},
new Report{Id=null,Date=Convert.ToDateTime("04/01/2017")},
new Report{Id=null,Date=Convert.ToDateTime("06/01/2017")},
};
reports.AddRange(report5);
foreach (var report in reports.OrderByDescending(x => x.Date))
{
Console.WriteLine("ID = " + report.Id + " " + "Date = " + report.Date);
}
Console.ReadKey();
}
}
class Report
{
public int? Id { get; set; }
public DateTime? Date { get; set; }
}
}
Sorting should be made based on the date and should not skip/move the null values of report list. Output should be as follows.
ID = 10004 Date =
ID = 10004 Date =
ID = 10004 Date = 07/01/2017
ID = Date = 06/01/2017
ID = 10003 Date =
ID = 10003 Date =
ID = 10003 Date = 05/01/2017
ID = Date = 04/01/2017
ID = 10002 Date =
ID = 10002 Date =
ID = 10002 Date = 03/01/2017
ID = Date = 02/01/2017
ID = 10001 Date =
ID = 10001 Date =
ID = 10001 Date = 01/01/2017
So, if I understood your answer correctly, you want to order by the ID's of the reports, and then the dates.
Change this:
foreach (var report in reports.OrderByDescending(x => x.Date))
{
Console.WriteLine("ID = " + report.Id + " " + "Date = " + report.Date);
}
to this:
foreach (var report in reports.OrderByDescending(x => x.Id).ThenBy(x => x.Date))
{
Console.WriteLine("ID = " + report.Id + " " + "Date = " + report.Date);
}
The latter sorts the reports by their ID, then by their date.
If I understood correctly, you want to order by Date first, and if Date is null, use ID for ordering. In this case, you need custom Report comparer.
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<Report> reports = new List<Report>();
Report[] report1 =
{
new Report {Id = 10001, Date = null},
new Report {Id = 10001, Date = null},
new Report {Id = 10001, Date = Convert.ToDateTime("01/01/2017")}
};
Report[] report2 =
{
new Report {Id = 10002, Date = null},
new Report {Id = 10002, Date = null},
new Report {Id = 10002, Date = Convert.ToDateTime("03/01/2017")}
};
Report[] report3 =
{
new Report {Id = 10003, Date = null},
new Report {Id = 10003, Date = null},
new Report {Id = 10003, Date = Convert.ToDateTime("05/01/2017")}
};
Report[] report4 =
{
new Report {Id = 10004, Date = null},
new Report {Id = 10004, Date = null},
new Report {Id = 10004, Date = Convert.ToDateTime("07/01/2017")}
};
reports.AddRange(report1);
reports.AddRange(report2);
reports.AddRange(report3);
reports.AddRange(report4);
var report5 = new List<Report>()
{
new Report {Id = null, Date = Convert.ToDateTime("02/01/2017")},
new Report {Id = null, Date = Convert.ToDateTime("04/01/2017")},
new Report {Id = null, Date = Convert.ToDateTime("06/01/2017")},
};
reports.AddRange(report5);
foreach (var report in reports.OrderByDescending(x => x, new ReportComparer()))
{
Console.WriteLine("ID = " + report.Id + " " + "Date = " + report.Date);
}
Console.ReadKey();
}
class ReportComparer: IComparer<Report>
{
public int Compare(Report x, Report y)
{
// write your ordering rules here
if (x.Date.HasValue && y.Date.HasValue)
{
return x.Date.Value.CompareTo(y.Date.Value);
}
return x.Id.Value.CompareTo(y.Id.Value);
}
}
class Report
{
public int? Id { get; set; }
public DateTime? Date { get; set; }
}
}
}
I would recommend not using linq for this.
I would create your own sort function.
Something like a bubble sort simple bubble sort
Where you can change the condition for swapping the elements.
You can do as assign you null Date with DateTime.MaxValue then order your list and reassign DateTime.MaxValue with null
var reportlist = reports.OrderBy(n => n.Date = n.Date == null ? n.Date = DateTime.MaxValue : n.Date).Select(n=>n = new Report() {Date= n.Date == DateTime.MaxValue ? n.Date = null : n.Date, Id=n.Id }).ToList();
foreach (var report in reportlist)
{
Console.WriteLine("ID = " + report.Id + " " + "Date = " + report.Date);
}

Unable to cast object of type 'System.Web.UI.WebControls.ListItem' to type 'System.IConvertible'

I am facing this but unable to solve it.This are from List. Having the problem at
AddOnTriggerItems = gvTriggerProduct.Rows.Cast<GridViewRow>().Select(rowItem => new AddOnTriggerItem()
ProjectA.TEST.BE.AddOn addOn = new ProjectA.TEST.BE.AddOn()
{
AddCode = addCode,
CreatedTime = DateTime.Now,
ModifiedTime = DateTime.Now,
AddOnTriggers = gvTriggerProduct.Rows.Cast<GridViewRow>().Select(row => new AddOnTrigger()
{
AddOnTriggerItems = gvTriggerProduct.Rows.Cast<GridViewRow>().Select(rowItem => new AddOnTriggerItem()
{
ProductTypeID = gvTriggerProduct.Rows[rowItem.RowIndex].Cells[1].Text.ToString(),
ProductCode = gvTriggerProduct.Rows[rowItem.RowIndex].Cells[2].Text.ToString(),
CreatedTime = DateTime.Now,
ModifiedTime = DateTime.Now
}).ToList(),
ActiveStatus = 1,
CreatedTime = DateTime.Now,
ModifiedTime = DateTime.Now
}).ToList(),
AddOnProducts = gvAddOnProduct.Rows.Cast<GridViewRow>().Select(rowAddOnProducts => new AddOnProduct()
{
ProductTypeID = gvAddOnProduct.Rows[rowItem.RowIndex].Cells[2].Text.ToString(),
ProductCode = gvAddOnProduct.Rows[rowItem.RowIndex].Cells[2].Text.ToString(),
CreatedTime = DateTime.Now,
ModifiedTime = DateTime.Now,
AddOnProductAllotments = addOnProductAllotmentSession.Where(p => (p.ProductID == (Convert.ToString(((HiddenField)rowAddOnProducts.FindControl("ProductID")).Value)))).ToList(),
}).ToList()
};
Thx to grek and derloopkat.
Grek's hint: the problem can be anywhere within the statement that starts in the error line
There are 3 parts that I changed.
I cannot have 2 gvTriggerProduct.
One part in my existing code(not here). Missing ".Value". Grek's hint Convert.ToByte(((DropDownList)rowItem.FindControl("ddlMinTriggerQuantity")).SelectedItem
Error: Cannot implicitly convert type 'void' to 'System.Collections.Generic.List'
List<AddOnTrigger> triggerlist = new List<AddOnTrigger>();
triggerList.Add(new AddOnTrigger
{
AddOnTriggerItems = gvTriggerProduct.Rows.Cast<GridViewRow>().Select(rowItem => new AddOnTriggerItem()
{
ProductTypeID = gvTriggerProduct.Rows[rowItem.RowIndex].Cells[1].Text.ToString(),
ProductCode = gvTriggerProduct.Rows[rowItem.RowIndex].Cells[2].Text.ToString(),
CreatedTime = DateTime.Now,
ModifiedTime = DateTime.Now
}).ToList(),
ActiveStatus = 1,
CreatedTime = DateTime.Now,
ModifiedTime = DateTime.Now}
});
ProjectA.TEST.BE.AddOn addOn = new ProjectA.TEST.BE.AddOn()
{
AddCode = addCode,
CreatedTime = DateTime.Now,
ModifiedTime = DateTime.Now,
AddOnTriggers = triggerlist
AddOnProducts = gvAddOnProduct.Rows.Cast<GridViewRow>().Select(rowAddOnProducts => new AddOnProduct()
{
ProductTypeID = gvAddOnProduct.Rows[rowItem.RowIndex].Cells[2].Text.ToString(),
ProductCode = gvAddOnProduct.Rows[rowItem.RowIndex].Cells[2].Text.ToString(),
CreatedTime = DateTime.Now,
ModifiedTime = DateTime.Now,
AddOnProductAllotments = addOnProductAllotmentSession.Where(p => (p.ProductID == (Convert.ToString(((HiddenField)rowAddOnProducts.FindControl("ProductID")).Value )))).ToList(),
}).ToList()
};

Unable to reproduce sum aggregate in MongoDB and C# driver

This MongoDB native query works just fine:
db.collection.aggregate([
{$project:{hour:{$hour:'$CreatedAt'},day:{$dayOfMonth:'$CreatedAt'},month:{$month:'$CreatedAt'},year:{$year:'$CreatedAt'}}},
{$group:{_id:{hour:'$hour',day:'$day',month:'$month',year:'$year'}, count: {$sum:1}}}
])
...but when I try to reproduce the same query in C#, the result is 0 for every sum (which is not the case when running the native query in Robomongo).
This is the C# code. I am failing to see any differences between both...
public Dictionary<DateTime, Int32> GetSumPerHour()
{
var project = new BsonDocument
{
{
"$project",
new BsonDocument{
{"hour", new BsonDocument{{"$hour","$CreatedAt"}}},
{"day", new BsonDocument{{"$dayOfMonth","$CreatedAt"}}},
{"month", new BsonDocument{{"$month","$CreatedAt"}}},
{"year", new BsonDocument{{"$year","$CreatedAt"}}},
}
}
};
var group = new BsonDocument
{
{
"$group",
new BsonDocument
{
{"_id", new BsonDocument {{"hour","$hour"},{"day","$day"},{"month","$month"},{"year","$year"}}},
{"count", new BsonDocument {{"$sum","1"}} }
}
}
};
var pipeline = new[] { project, group };
var arguments = new AggregateArgs { Pipeline = pipeline };
var results = this.collection.Aggregate(arguments);
var timeValueDictionary = new Dictionary<DateTime, Int32>();
foreach (BsonDocument result in results)
{
int hour = result["_id"]["hour"].AsInt32;
int day = result["_id"]["day"].AsInt32;
int month = result["_id"]["month"].AsInt32;
int year = result["_id"]["year"].AsInt32;
DateTime time = new DateTime(year, month, day, hour, 0, 0);
int count = result["count"].AsInt32;
timeValueDictionary.Add(time, count);
}
return timeValueDictionary;
}

Categories