find and replace result of a list with linq - c#

Is there a way to replace the value of one result with another after doing a linq statement?
is that in my linq statement in ** Status **, there are some that come to me with this result "PendingForApprover" but I want to replace it with "Pending for approver", I would like that after obtaining the result, you can use a find and based on that replace the values, before in my model I had it with a data annotation with a display name but for the reason that that result I am going to transform it into JSON and then it will be brought by server side that method is not working
y share my sentence LINQ
var result = db.document.Select(d => new DocumentViewModel
{
DocumentId = d.DocumentId,
Name = w.name
ReceivedLogs = d.Logs
Status = w.Status.toString(),
.Where(l => l.Status == Status.Received)
.Select(l => new LogViewModel
{
CurrentApprover = l.User,
NameApprover = l.User.FullName
}).FirstOrDefault()
}).ToList();
thanks

Have you tried with Switch expressions it is a pretty clear solution and you can integrate it in your LINQ query.
Status = w.Status switch
{
Status.StatusOne => "Status One",
Status.PendingForApprover => "Pending for approver",
_ => "Unknown"
}

Related

Mongo C# filter on integer contains

I've a collection with orders, each with an OrderId field of type int32. I would like to filter the collecting and get all orders where the OrderId contains e.g. 123. For instance the following OrderIds must match:
123
9912399
99123
The following raw mongo filter works:
{ $where: "/^.*123.*/.test(this.OrderId)" }
How can this be expressed in the C# Mongo client or something different that does the job?
I'm not able to use the below code, as it seems to only work in string fields:
Builders<Order>.Filter.Regex(x => x.OrderId, new BsonRegularExpression("123"))
ideally you should store a string version of the order id in your documents. in case that's not an option you can do the following aggregation pipeline:
var res = await collection
.Aggregate()
.AppendStage<object>("{ $set : { orderIdString : { $toString : '$OrderId' } } }")
.Match(Builders<object>.Filter.Regex("orderIdString", "/123/"))
.AppendStage<object>("{ $unset : 'orderIdString' }")
.As<Order>()
.ToListAsync();
I don't think you can generate $where via typed builders. So, as it was mentioned above, the only option you have is to create a filter from a raw MQL like below:
var coll = db.GetCollection<Order>("coll");
var result = coll.Find("{ $where: '/^.*123.*/.test(this.OrderId)' }").ToList();
Did you try using:
x => x.OrderId.ToString()
instead of
x => x.Orderid
You can use Filter.Regex to achieve the desired behavior:
var valueToFilterBy = "123"
var filter = Builders<Order>.Filter.Regex(nameof(Order.Id), new BsonRegularExpression($".*{valueToFilterBy}.*"));
var data = await collection.FindAsync(filter).ToListAsync();

MVC SqlQuery and a 2nd sort

I am re-writing an existing legacy system that uses stored procedures to retrieve the data needed.
The new design will have the normal column sorting and text filtering, but I came across something that has me stumped.
I am able to perform a LINQ query on the retrieved data and get my desired result as follows:
var customerIDParam = new SqlParameter("#customerID", 452);
var result =
db.Database.SqlQuery<InventoryDetail>("map_efs_InventoryDetail #customerID", customerIDParam).ToList();
// this works!
var finalResult1 = from s in result
.Where(s => s.cProductDescription.Contains("E"))
.OrderBy(s => s.cProductDescription)
select s;
return View(finalResult1.ToList());
I would really like to build the LINQ statement dynamically as follows BUT THIS FAILS, always returning the full query
var customerIDParam = new SqlParameter("#customerID", 452);
var result =
db.Database.SqlQuery<InventoryDetail>("map_efs_InventoryDetail #customerID", customerIDParam).ToList();
// This does not work ???
var finalResult2 = from s in result select s;
finalResult2.OrderBy(s => s.cProductDescription);
finalResult2.Where(s => s.cProductDescription.Contains("E"));
return View(finalResult2.ToList());
If anyone can assist I would appreciate it.
Regards
Mark
OrderBy/Where/Etc are "pure" methods, they will return an other IEnumerable, so your result never gets ordered or filtered, you need to assign the new operations (I say operations beacuse IEnumerables have deferred execution), eg:
Assigning variables:
List<Customer> customers = context.Customers.ToList();
IEnumerable<Company> companies = customers.Select(e => e.Company);
IEnumerable<Company> companiesFiltered = companies.Where(e => e.Active);
IOrderedEnumerable<Company> companiesOrdered = companiesFiltered.OrderBy(e => e.Id);
companiesFiltered = companiesOrdered.ThenBy(e => e.Code); // because the variable and result are the same type we can do this
Using returning values:
var finalResult2 = result.Select(r => r.s)
.Where(s => s.cProductDescription.Contains("E"))
.OrderBy(s => s.cProductDescription);
Because every operation returns another IEnumrable we can "chain calls" fluently like that. Remember that actual execution takes place when you call ToList().
I discovered my own error.
var finalResult2 = from s in result select s;
finalResult2 = finalResult2.OrderBy(s => s.cProductDescription);
finalResult2 = finalResult2.Where(s => s.cProductDescription.Contains("E"));
return View(finalResult2.ToList());

asp.net MVC Where in List

I building my first application with c# and sp.net MVC 5, so far so good :)
Now I have a problem, we using 2 User Tables, first one contains the username, other the user data.
string user = User.Identity.Name;
var data = db.FE_Benutzer;
var collection = data.Where(o => o.Benutzername == user).Select(x => new
{
id = x.ID,
name = x.Name,
hauptbereiche = x.Hauptbereich.ToList()
});
var dataHauptbereich = db.Hauptbereich;
var collectionHauptbereich = dataHauptbereich.Where(o => collection.ElementAt(0).hauptbereiche.Contains(o)).Select(x => new
{
id = x.ID,
name = x.Name
});
return Json(collectionHauptbereich, JsonRequestBehavior.AllowGet);
I getting this error
LINQ to Entities does not recognize the method '<>f__AnonymousType63[System.Int32,System.String,System.Collections.Generic.List1[scorring.Models.Hauptbereich]] ElementAt[<>f__AnonymousType63](System.Linq.IQueryable1[<>f__AnonymousType63[System.Int32,System.String,System.Collections.Generic.List1[scorring.Models.Hauptbereich]]], Int32)' method, and this method cannot be translated into a store expression.
hauptbereiche = x.Hauptbereich.ToList()
contains a list of ids where the user have premission to.
When I fetching the data
dataHauptbereich.Where
I wont to include only the ids I have in the list
how is this possible?
Entity Framework doesn't know how to turn ElementAt into SQL. See this answer for more information: Getting the first result from a LINQ query - why does ElementAt<T>(0) fails when First<T>() succeeds?
Try
dataHauptbereich.Where(o => collection.ElementAt(0).hauptbereiche.Any(h => h.ID == o.ID))
Or
dataHauptbereich.Where(o => collection.Any(c => c.hauptbereiche.Any(h => h.ID == o.ID)))
I'm having a bit of a time deciphering exactly what you're trying to achieve with your code here, but it looks to me like your simply querying Hauptbereichs that belong to a particular user. Your first query selects an anonymous object composed of id, name and hauptbereiche, but of these you only ever use the hauptbereiche property. Then, in your second query, you merely selecting Hauptbereichs that match an item in this hauptbereiche property's collection. Actually, here, you're only comparing values from the first item in the original collection, which begs the question of why you're selecting anything other than the first item. That, and this second query is entirely redundant because if the items match that means you already had the items in the first place. You could get the same info directly from collection.ElementAt(0).hauptbereiche without issuing the second query.
So, here's a couple of simpler options:
If you're trying to get all the Hauptbereichs that belong to all the FE_Benutzers where Benutzername == user then just do:
var collectionHauptbereich = db.FE_Benutzer.Where(m => m.Benutzername == user)
.Include(m => m.Hauptbereich)
.SelectMany(m => m.Hauptbereich);
If you want just the first FE_Benutzer item's Hauptbereichs, then do:
var benutzer = db.FE_Benutzer.Where(m => m.Benutzername == user)
.Include(m => m.Hauptbereich)
.FirstOrDefault();
var collectionHauptbereich = benutzer != null
? benutzer.Hauptbereich.ToList()
: new List<Hauptbereich>();

Multiple property Full-Text Search with MongoDB

I've this C# code to query my MongoDB collection:
var query = myCollection.FindAll().AsQueryable();
if (!string.IsNullOrWhiteSpace(username))
query = query.Where(
x => x.User.FullName.IndexOf(username, StringComparison.OrdinalIgnoreCase) >= 0);
if (!string.IsNullOrWhiteSpace(productName))
query = query.Where(
x => x.Product.ProductName.IndexOf(productName, StringComparison.OrdinalIgnoreCase) >= 0);
query = query.Take(pageSize).Skip(pageSize*(pageNumber-1));
var itemCount=query.Count();
var result = query.ToList();
Due to low performance now I want to use a full-text search. I created text index for User.FullName and Product.ProductName and I started to write code like this:
var textSearchCommand = new CommandDocument
{
{ "text", myCollection.Name },
{ "search", username }
};
var commandResult = _database.RunCommand(textSearchCommand);
var result = commandResult.Response;
Now I'm stuck; How to specify the property name in the above syntax example? Is this the right way to do that?
A text index points to the document as a whole, not to the individual field where the match occurs. That means a text-search is always performed on all fields which are part of the text-index. You can not selectively only search for matches in one field.
But what you can do is further filter the result-set of the $text-operator with additional operators. You could, for example, use an additional $regex-operator to check if the string you searched for occurs in the field where you want it to be.

How to build a LINQ to XML query with a conditional selection

The xml elements are variable depending on some conditional. I need to initialize an instance with a different element, based on the value of some other element.
var result = (from name in names
select new MyName
{
name.First = name.Type = Fracais ? name.PreNom : name.First,
name.Last
}
Any ideas?
What you have is almost right. I had to guess the enums and members as you don't provide the other classes:
var result = from name in names
select new Person()
{
First = name.Type == PersonType.Fracais ? name.PreNom : name.First,
Last = name.Last
};
You can have pretty much any expression, including function calls, in a linq query, so testing values and mutating them on the fly is perfectly acceptable.
How about this? As a pointless alternative.
var result = names.where(name => name.Type == Francais).Select(name =>
name.PreNom, name.Last).Union()
names.where(name => name.Type != Francais).Select(name.First, name.Last);

Categories

Resources