I have a class:
public class FlightDetails
{
public string FlightId {get; set;}
public string PilotName {get; set;}
public string Area {get; set;}
public string Country {get; set;}
}
Here sending response:
public async Task<List<FlightDetails>> GetFlightAsync(string FlightId)
{
//
var flights = new List<FlightDetails>();
flights = response.AllFlights;
flights = flights.Where(x => x.FlightId.Contains(FlightId)).ToList();
//
return flights;
}
Getting List here and data is filled but issue is don't want FlightId and Country in the response which I am sending. How to remove this objects in the List? Finally in the List item there should be only PilotName and Area.
Update:
I forgot the following line before the flights = response.AllFlights;
var request = await _rest.Get<WorldFlights>(url + $"?FlightId={FlightId}");
You will need to create another object, and map there only the properties you want. For example:
public class FlightDetailsResponse
{
public string PilotName {get; set;}
public string Area {get; set;}
}
And then in the function:
public async Task<List<FlightDetailsResponse>> GetFlightAsync(string FlightId){
var flights = response.AllFlights;
var flightResponses = flights
.Where(x => x.FlightId.Contains(FlightId).ToList())
.Select(x => new FlightDetailsResponse{
PilotName = x.PilotName,
Area = x.Area
});
return flightResponses;
}
This way the response will only contain the PilotName and Area fields.
PD: What I wrote might not compile because of missing commas or something like that. Sorry, it has been some time since I last wrote C#, but the idea is that.
Related
I have a Collection Students which Stores registered students data in MongoDB. It has StudentName, SaveDate etc. fields. I am displaying the details to my website from my .net framework WebAPI.
What I want to do is Get StudentDetails with prev next student ID's by the order of SaveDate.
My current query gets Student details by student id from below query,
var collection = StudentDB.Collection<Student>("StudyMaterials");
var curfilter = Builders<Student>.Filter.Eq(x => x.studentID, studentID);
studentDetails= collection.Find(curfilter).FirstOrDefault();
This is my Student.cs class,
public class Student
{
[BsonRepresentation(BsonType.String)]
public Guid StudentID {get; set;}
public string StudentName {get; set;}
[BsonRepresentation(BsonType.String)]
public Guid NextStudentID {get; set;}
[BsonRepresentation(BsonType.String)]
public Guid PrevStudentID {get; set;}
}
I want to use aggregation but don't know how to sort by multiple sort definitions on the aggregation framework.
First of all, I don't think you need to keep the students like that. I suggest the following:
public class Student
{
public ObjectId Id { get; set; }
public string Name { get; set; }
public DateTime SaveDate { get; set; }
}
You need to make sure that the documents are sorted by SaveDate. For instance, when inserting new students into the database you can do it like this:
var student = new Student
{
Name = "Sara",
SaveDate = DateTime.UtcNow
};
context.Students.InsertOne(student);
Now, you can get the documents with Skip and Limit:
var skip = 0;
var limit = 1;
var context = new MongoContext();
var filter = Builders<Student>.Filter.Empty;
var result = context.Students.Find(filter).Skip(skip).Limit(limit).FirstOrDefault();
Increment skip to get next and so on.
Ok so the title is very confusing, my apologies.
I have a list of objects, each with an identifier and a second property:
public class someFoo
{
int Identifier {get; set;}
someType someBar {get; set;}
}
And I have a list of identifiers. I want to select the objects with a matching identifier and set someBar on those objects. Whats the most efficient way to do this in c#?
Why not using class instead of object?
public class someFoo
{
int Identifier {get; set;}
someType someBar {get; set;}
}
List<someFoo> yourList = new List<someFoo>();
// fill your list here.
someFoo specifiedFoo = yourList.Where(i=> i.Identifier == X).FirstOrDefault();
// x = your id
// you also need to import Linq.
specifiedFoo.someBar = yourBar; // set it with your bar.
The code below is checking every value in the list of "yourValues" from "yourList" and if exists; adding them in "existingList".
List<someFoo> yourList = new List<someFoo>();
List<int> yourValues = new List<int>();
List<someFoo> existingList = new List<someFoo>();
yourList = database.GetMyList(); // For example i filled the first list with datas coming from database.
foreach (var x in yourValues)
{
someFoo existingFoo = yourList.Where(i => i.Identifier == x).FirstOrDefault();
if(existingFoo != null)
{
// Do your things here
existingFoo.someBar = myBar;
existingList.Add(existingFoo);
}
}
public class SomeFoo
{
public int Identifier {get; set;}
public someType someBar {get; set;}
}
public void DoStuff(IEnumerable<SomeFoo> foos, IEnumerable<int> ids)
{
//Algorithimically searching for a value in a Set is faster than in a list
ISet<int> idsAsSet = ids as ISet<int> ?? new HashSet<int>(ids);
var itemsWeWantToChange = foos.Where(f => idsAsSet.Contains(f.Identifier ));
foreach(var item in itemsWeWantToChange)
{
item.someBar = ...
}
}
I have following classes:
public class QualifyResponse
{
public Message[] MessageList{get; set;}
}
public class Message
{
public MessageDetail[] MessageDetailList{get; set;}
public string MessageStatus{get; set;}
public string ProviderCode{get; set;}
}
public partial class MessageDetail
{
public string MessageCategory{get; set;}
public string MessageCode{get; set;}
public string MessageSeverity{get; set;}
public string MessageText{get; set;}
}
What I want is, For all the MessageDetailList, if the messageCode is equal to "status" then assign its messageText value to "Complete" after this query
I tried the following LINQ, but it didnt work i.e the MessageDetailList objects having MessageCode = "status" didn't have MessageText = "Complete".
response.MessageList.FirstOrDefault()
.MessageDetailList
.Where(message => message.MessageCode
.ToLower()
.Equals("status"))
.ToList()
.ForEach(status =>
{
status.MessageText = "Complete";
});
What am I doing wrong?
A bit of formatting helps read your code
However this should help and double check the results
Note if your Where clause is correct it WILL update your
MessageText providing there isn't some funky setter going on
var message = response.MessageList.FirstOrDefault();
var messageDetails = message.MessageDetailList
.Where(message => message.MessageCode.ToLower() == "status")
.ToList();
messageDetails.ForEach(status => status.MessageText = "Complete");
messageDetails.ForEach(status => Debug.WriteLine(status.MessageText));
Update
This all should work fine
Try a foreach instead
Try putting a try catch around it all
Try checking the result immediately after you are setting it.
If this from Ef try `SaveChanges'
We don't know how you are checking your results
I have 3 Tables defined as below:
public Class Product
{
public long Key {get; set;}
public CountryKey {get; set;}
}
public Class ProductCountry
{
pullic long Key {get; set;}
public long ProductKey {get; set;}
public LocalProductKey {get; set;}
public long CountryKey {get; set;}
}
public Class Country
{
public long Key {get; set;}
public string Name {get; set;}
}
I'm using EF database first, for each class we have a view to get data from database ( VW_Product to get the products)
I have a method filtering a collection of product depends on a criteria.
IQueryable<VW_Product> query1 = FilterQuery(Object criteria); gets all products matching the criteria;
Now I want concat the filtred collection by adding the folowing collection:
var countriesKey = new List<long>() {45, 36, 6974, 366,....};
var keys = Context.VW_ProductCountries
.GroupBy(pc => pc.ProductKey)
.Where(grp => grp.Any(pc => countriesKey.Contains(pc.CountryKey) && !grp.Any(x => x.LocalProductKey != null)))
.SelectMany(grp => grp.Select(pc => pc.Productkey))
.Distinct();
var query2 = Context.VW_Product.Where(p => keys.Contains(p.ProductKey));
var result = query1.Concat(query2);
Is the another way to improve this query because it takes a lot of time to execute.
Try adding a .ToList() after .Distinct() to transform the list of keys from an ObjectQuery to an in-memory object. In query2, you're running multiple .Contains() against the 'keys' ObjectQuery, possibly executing the query every time.
Also, i presume
var result = query1.Concat(query1);
should be
var result = query1.Concat(query2);
public class Student
{
public long StudentId {get; set;}
public string Fname {get; set;}
public string Lname {get; set;}
public List<ObjectId> CoursesList {get; set;}
public int IQ {get;set;}
}
public class Courses
{
[BsonId]
public ObjectId Id { get; set; }
public string CourseNumber{get; set;}
public string CourseName{get; set;}
}
How do I add/append a courser Id to Course list(which may be null for the first time) of a Student object
PS: I know how to set a field using the below command. I am hoping it is on similar lines for the above problem
await StudentCollection.UpdateOneAsync(a => a.StudentId == studentId, Builders<Student>.Update.Set( a => a.IQ,90));
As you've already discovered, the C# code to use $addToSet is:
var filter = Builders<Student>.Filter.Eq(s => s.StudentId, studentId);
var update = Builders<Student>.Update.AddToSet(s => s.CoursesList, courseId);
var result = await collection.UpdateOneAsync(filter, update);
However, $addToSet is not going to work if the CourseList member has been stored in the collection as a null. The server requires that the existing value for $addToSet be an array (it can be an empty array).
The easiest solution is to just store an empty list for CoursesList instead of a null when there are no courses.
This is working for me. When you define "List" like this, it will be empty and works with AddToSet/Push methods.
public List<ObjectId> CoursesList = new List<ObjectId>();
The only case that you have to pay attention is when the array CourseList is null, in this case you have to use the code below (see also here):
var newListOfObject = new List<ObjectId>(){...}
await StudentCollection.UpdateOneAsync(a => a.StudentId == studentId, Builders<Student>.Update.Set( a => a.CoursesList, newListOfObject));
Otherwise you can use AddToSet or Push like explain in the other answers.