How to Convert List<'a> to other object list? - c#

i want result linq statement convert to other list in Web Api
var data = Base_Tables.db.Lines.Find(id).Owner_Line.OrderByDescending(x => x.ID)
.Select(x => new { x.ID, Caption = x.Name1 + " " + x.Name2 + " " + x.Name3 })
.ToList();
List<HistoryLine> historyList = data as List<HistoryLine>();
Class HistoryLine
public class HistoryLine
{
public long ID { get; set; }
public string Caption { get; set; }
}
How to Convert ? , if can't convert statement, any way to fix this problem ?

Simply select into the object you want instead of an anonymous type.
var data = Base_Tables.db.Lines
.Find(id).Owner_Line
.OrderByDescending(x => x.ID)
.Select(x => new HistoryLine {ID = x.ID, Caption = x.Name1 + " " + x.Name2 + " " + x.Name3})
.ToList();
data is now a List<HistoryLine>

Related

Multi column lambda expression

Upon completeing the tutorial here:
https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application
I currently use the following
userAccesses = userAccesses.Where(s => s.employeeDetail.employeeNumber.ToUpper().Contains(searchValue.ToUpper()));
However I'd like to concatenate the knownas / surname columns and then do the contains on the concatenated items.
Could anyone explain/suggest an example syntax?
This is what I've attempted below but I'm certain my syntax is incorrect.
userAccesses = userAccesses.Where(s => s.employeeDetail.employeeNumber + " " + s.employeeDetail.knownas + " " + s.employeeDetail.surname).Contains(searchValue);
Thanks for the response everyone, final working version is below.
userAccesses.Where(x => (x.employeeDetail.employeeNumber + x.employeeDetail.knownas + x.employeeDetail.surname).Contains(searchValue));
You should go to this direction
public class Employee
{
public string knownas { get; set; }
public string userName { get; set; }
}
public void Test()
{
List<Employee> employess = new List<Employee>();
string searchvalue = "test";
var listEmplyer = employess.Where(x => (x.userName + x.knownas).Contains(searchvalue));
}
You'll simply need to concatenate the string and call Contains on that string.
userAccesses
.Where(s => $"{s.employeeDetail.employeeNumber} {s.employeeDetail.knownas} {s.employeeDetail.surname}".Contains(searchValue))
If you need an enumerable of strings as the result of the expression, you can also choose to use the following:
userAccesses
.Select(s => $"{s.employeeDetail.employeeNumber} {s.employeeDetail.knownas} {s.employeeDetail.surname}")
.Where(s => s.Contains(searchValue))
Searching through concatenated column values is weird...
I'd suggest smth like this:
var filtered = userAccesses.Where(s => s.employeeDetail.employeeNumber.Contains(searchValue)
|| s.employeeDetail.knownas.Contains(searchValue)
|| s.employeeDetail.surname.Contains(searchValue));

Creating Alias in LINQ with SelectMany

I have a viewmodel like this:
public class FileInfo
{
private string _fileNo;
private string _fileName;
public string FileNo
{
get
{
return _fileNo;
}
set
{
_fileNo = value;
}
}
public string FileName
{
get
{
return _fileName;
}
set
{
_fileName = value;
}
}
}
I have a List DataList with data and FileNo may have duplications.
I can use below LINQ to get all data from DataList with condition like this:
List<FileInfo> ViewList = DataList.Where(x => !string.IsNullOrWhiteSpace(x.FileName))
.GroupBy(y => y.FileNo)
.SelectMany(z => z).ToList();
How of I get Alias name in the SelectMany and also .ToList() for above query, it should look something like this:
List<FileInfo> ViewList = DataList.Where(x => !string.IsNullOrWhiteSpace(x.FileName))
.GroupBy(y => y.FileNo)
.SelectMany(new {...NewFileName = "Row " + FileNo + FileName, NewFileNo = "No " + FileNo}).ToList();
Any pointers would be highly appreciated
Thanks
Try as below -
var ViewList =
DataList
.Where(x => string.IsNullOrWhiteSpace(x.FileName))
.GroupBy(y => new { FileNo = y.FileNo })
.SelectMany(x =>
x.Select(y => new
{
NewFileName = "Row " + y.FileNo + y.FileName,
NewFileNo = "No " + y.FileNo
}))
.ToList();

How to concatenate multiple XML childnodes into one in a ListView row?

I'm developing an application that queries MusicBrainz for data and I'm viewing it by binding the results to ListViews using some XPath.
Now, the underlying XML for the second (albums) ListView is here, and as you can see the top result has two artists:
<metadata created="2013-05-10T21:32:13.487Z">
<release-group-list count="153471" offset="0">
<release-group id="22315cdd-4ed9-427c-9492-560cf4afed58" type="Album" ext:score="100">
<title>The Heist</title>
<primary-type>Album</primary-type>
<artist-credit>
<name-credit joinphrase=" & ">
<artist id="b6d7ec94-830c-44dd-b699-ce66556b7e55">
<name>Macklemore</name>
<sort-name>Macklemore</sort-name>
</artist>
</name-credit>
<name-credit>
<artist id="c01560d1-6f69-48cf-a3c6-c94b65f099b1">
<name>Ryan Lewis</name>
<sort-name>Lewis, Ryan</sort-name>
</artist>
</name-credit>
</artist-credit>
but using this code
View.SetBinding(ListView.ItemsSourceProperty, new Binding()
{
Source = Resources["DataProvider"],
XPath = "//a:metadata/a:release-group-list/a:release-group"
});
GridView.Columns.Add(new GridViewColumn()
{
DisplayMemberBinding = new Binding() { XPath = "a:artist-credit/a:name-credit/a:artist/a:name" },
Header = "Artist",
Width = 128
});
I only get the first result and I have no idea how to go about concatenating them.
Any insight will be greatly appreciated.
Here is a way to get the data that you're talking about via Linq-to-Xml:
public class XmlArtistsConcept
{
public void Run()
{
XDocument artistDocument = XDocument.Load(#"http://musicbrainz.org/ws/2/release-group?query=the%20heist");
XNamespace artistNamespace = #"http://musicbrainz.org/ns/mmd-2.0#";
// The purpose of this query is to demonstrate getting this for a particular result.
var theHeistNames =
string.Join(", ",
artistDocument
.Element(artistNamespace + "metadata")
.Element(artistNamespace + "release-group-list")
.Elements(artistNamespace + "release-group")
.Where(element => element.Attribute("id").Value == "22315cdd-4ed9-427c-9492-560cf4afed58").Single()
.Elements(artistNamespace + "artist-credit")
.Elements(artistNamespace + "name-credit")
.Elements(artistNamespace + "artist")
.Select(artist => artist.Element(artistNamespace + "name").Value).ToArray());
Console.WriteLine(theHeistNames);
// This query will get it for everything in the XDocument. I made a quick data bucket to dump the values in.
var allAlbumResults =
artistDocument
.Element(artistNamespace + "metadata")
.Element(artistNamespace + "release-group-list")
.Elements(artistNamespace + "release-group")
.Where(releaseGroup => releaseGroup.Attribute("type") != null)
.Select(releaseGroup =>
{
return new AlbumResult()
{
Title = releaseGroup.Element(artistNamespace + "title").Value,
Artist = string.Join(", ",
releaseGroup
.Elements(artistNamespace + "artist-credit")
.Elements(artistNamespace + "name-credit")
.Elements(artistNamespace + "artist")
.Select(artist => artist.Element(artistNamespace + "name").Value)
.ToArray()),
Type = releaseGroup.Attribute("type").Value,
};
});
allAlbumResults.ToList().ForEach(albumResult => Console.WriteLine("Title: {0}, Artist: {1}, Type: {2}", albumResult.Title, albumResult.Artist, albumResult.Type));
Console.WriteLine();
Console.WriteLine("Finished");
}
}
public class AlbumResult
{
public string Title { get; set; }
public string Artist { get; set; }
public string Type { get; set; }
}

c# Web Service Sorting Result

I am trying to sort this select by vehicle.DateRegistered but its really confusing me and nothing i seem to do works. Any help would be much appreciated.
var lookupValues = vehicles
.Select(vehicle =>
new LookupValue()
{
Id = vehicle.Id,
Description = vehicle.RegistrationNumber + " " +vehicle.DateRegistered.ToString("dd/mm/yyyy"),
Data = Json.GetString(vehicle),
Active = true
});
return lookupValues;
Thanks Austin
Use the OrderBy extension method:
var lookupValues = vehicles.OrderBy(v => v.DateRegistered).Select(.....);
You can try with this code - based on OrderBy Linq operator
lookupValues.OrderBy(a=> a.DateRegistered);
Nota : Add DateRegistered in your selector
Or also you can use this
var lookupValues = vehicles
.OrderBy(a => a.DateRegistered)
.Select(vehicle =>
new LookupValue()
{
Id = vehicle.Id,
Description = vehicle.RegistrationNumber + " " +vehicle.DateRegistered.ToString("dd/mm/yyyy"),
Data = Json.GetString(vehicle),
Active = true
});
return lookupValues;
Nota : you define direction of order : descending or ascending
var lookupValues = vehicles
.OrderBy(vehicle => vehicle.DateRegistered)
.Select(vehicle =>
new LookupValue()
{
Id = vehicle.Id,
Description = vehicle.RegistrationNumber + " " +vehicle.DateRegistered.ToString("dd/mm/yyyy"),
Data = Json.GetString(vehicle),
Active = true
});
return lookupValues;

Order By Date print Latest 20 records only in LINQ

I am Printing all latest records depending on when a book was published.(PubEnd). Now I am able to print all the books that are published in descending order.
I need to print the 20 Latest published titles. How can I do that??
Right now the code below is printing all books published in descending order.
var query = docs.Descendants(name)
.Select(x => new
{
Title = (string)x.Element(ns + "TITLE"),
Status = (string)x.Element(ns + "STATUS"),
PubEnd = (string)x.Element(ns + "PUB_END")
})
.Select(x => new
{
Title = x.Title,
Status = x.Status,
PubEnd = x.PubEnd,
}).OrderByDescending(x => x.PubEnd).ToList();
foreach (var book in query)
{
if (book.Status == "Published")
{
Response.Write(book.Title);
Response.Write(book.Status);
Response.Write(book.PubEnd);
}
}
Use Take():
foreach (var book in query.Take(20))
{
//print
}
If you always only need 20 update the query itself accordingly:
(..).OrderByDescending(x => x.PubEnd).Take(20).ToList();
You should just need to use Take(20)
Here is the documentation on Take
Your code will become:
...OrderByDescending(x => x.PubEnd).Take(20).ToList()
UPDATE for DISTINCT
Here is the documentation for Distinct
Your code would be this, I assume you want distinct before you take 20 :)
...OrderByDescending(x => x.PubEnd).Distinct().Take(20).ToList()
use Take(20)
Why are you building anonumous objects twice with the same values?
This should be what you need:
var list = docs.Descendants(name)
.Select(x => new
{
Title = (string)x.Element(ns + "TITLE"),
Status = (string)x.Element(ns + "STATUS"),
PubEnd = (string)x.Element(ns + "PUB_END")
})
.OrderByDescending(x => x.PubEnd).Take(20).ToList();
If you want to get distinct result:
var list = (...).OrderByDescending(x => x.PubEnd).Distinct().Take(20).ToList();
var query = docs.Descendants(name)
.Select(x => new
{
Title = (string)x.Element(ns + "TITLE"),
Status = (string)x.Element(ns + "STATUS"),
PubEnd = (string)x.Element(ns + "PUB_END")
})
.OrderByDescending(x => x.PubEnd).Take(20); // Take will get the first N records.
foreach (var book in query)
{
if (book.Status == "Published")
{
Response.Write(book.Title);
Response.Write(book.Status);
Response.Write(book.PubEnd);
}
}

Categories