I have a database table with a column name FILES.
The data for the FILES column looks like this
//directory/anotherdirectory/file1.txt
//directory/anotherdirectory/file2.txt
//directory/anotherdirectory/file3.txt
I want the linq to create a string like
"file1.txt\nfile2.txt\file3.txt"
I want to be able to select the column and parse the data at the same time.
The following two ways give errors.
string filesNames = string.Join("\n", _repositoryFactory
.GetRepository<MyResponseEntity>()
.Entity
.ByMyId(id).Select(x => {x.FILES = "Just a test"; return x}).ToArray());
I have also tried do a substring with no luck
string filesNames = string.Join("\n", _repositoryFactory
.GetRepository<MyResponseEntity>()
.Entity
.ByMyId(id).Select(x => x.FILES.Substring(x.FILES.LastIndexOf('/')+1,
x.FILES.Length - (x.FILES.LastIndexOf('/')+1)).ToArray());
Using Aggregate method.
var fileNames = _repositoryFactory
.GetRepository<MyResponseEntity>()
.Entity
.ByMyId(id)
.Select(e => e.Substring(e.LastIndexOf('/') + 1))
.Aggregate((a, b) => a + "\n" + b);
string filesNames = string.Join("\n", _repositoryFactory.GetRepository<MyResponseEntity>()
.Entity.ByMyId(id).Select(x => Path.GetFileName(x.FILES)).ToArray());
Related
I am trying to recreate the SQL condition of: like '1 %'.
The column in the table contains two sets of values separated by a space. Using StartsWith(glassTag) returns any row where the column starts with '1'. It seems to do a trim on the string before testing the condition. But, if I use StartsWith("1 "), it returns the rows I expect.
What am I doing wrong?
This is a LINQ to Entity question. SqlMethods are not compatible.
the following returns where the Name is: "119 GL-01"
var glassTag = "1 ";
var gItem = await _context.Items.Where(x => x.Name.StartsWith(glassTag) && x.Material.MaterialType.Name.Equals("Glass") && x.JobItems.Any(j => j.Job.Code.Equals(pCode))).ToListAsync();
The code below returns the results I expect
var gItem = await _context.Items.Where(x => x.Name.StartsWith("1 ") && x.Material.MaterialType.Name.Equals("Glass") && x.JobItems.Any(j => j.Job.Code.Equals(pCode))).ToListAsync();
StartsWith simply doesn't work for a variable being passed when looking for spaces at the end.
I have captured the sql being generated by EF.
The code below generates the sql directly below it. When passing a variable to the StartsWith condition, it doesn't use "like". And it creates something that isn't right.
var gItem = _context.Items.Where(x => x.Name.StartsWith(gd.glasstag + " "));
DECLARE #__glassTag_0 nvarchar(4000) = N'1 ';
SELECT [i].[ItemId], [i].[Name]
FROM [Item] AS [i]
WHERE (#__glassTag_0 = N'') OR ([i].[Name] IS NOT NULL AND (LEFT([i].[Name], LEN(#__glassTag_0)) = #__glassTag_0))
The code below generates the sql below it. Note, it uses the "like" condition.
var gItem = _context.Items.Where(x => x.Name.StartsWith("1 "));
SELECT [i].[ItemId], [i].[Name]
FROM [Item] AS [i]
WHERE [i].[Name] IS NOT NULL AND ([i].[Name] LIKE N'1 %')
So, I will be creating a stored procedure to retrieve the data I need. The code will look like this:
var glassTag = gd.glasstag + " ";
var gItem = await _context.Items.FromSqlRaw($"spItemsByGlassTag '{pCode}', '{glassTag}'").ToListAsync();
I want to capture the column names which needs to be added to the SQL table in order to insert the data.
Columnspresent-- List of all columns in the file ("Node", "Logtime", "Reason","ID","Comments")
existingtablecolumnsPresent -- List of all columns in the existing table in SQL("Node","Value","Reason","ID","Comments","logtime")
columnsNotPresent -- List of columns that needs to be added to the SQL table ( have to get "Value" in the output but not getting)..
List<string> columnsPresent =
dt.Columns.Cast<DataColumn>()
.Select(a => a.ColumnName.ToLower())
.ToList();
List<string> existingtablecolumnsPresent =
existingtable.Columns.Cast<DataColumn>()
.Select(a => "[" + a.ColumnName.ToLower() + "]")
.ToList();
List<string> columnsNotPresent =
columnsPresent.OrderBy(t => t)
.Except(existingtablecolumnsPresent.OrderBy(t => t))
.ToList();
The above code is not giving the correct results if there is change in order of columns .Please advise.
you may try this (it needn't order by..)
List<string> existingtablecolumnsPresentNoSqrBr = new List<string>();
existingtablecolumnsPresent.ForEach(c => {
c = c.Replace("[", string.Empty);
c = c.Replace("]",string.Empty);
existingtablecolumnsPresentNoSqrBr.Add(c);
});
List<string> columnsNotPresent =
columnsPresent.Except(existingtablecolumnsPresentNoSqrBr)
.ToList();
really, if you avoid to .Select(a => "[" + a.ColumnName.ToLower() + "]") you can use the second query directly on existingtablecolumnsPresent..
am a newbie in linq.. am stuck with one scenario. ie,
i have to sort the search results based on user input.
user inputs are Last Name, First Name and Title. for input 3 drop downs are there and i have to sort result based on the values selected.
i tried
order = Request["orders"].Split(',');
var param = order[0];
var p1 = typeof(Test).GetProperty(param);
param = order[1];
var p2 = typeof(Test).GetProperty(param);
param = order[2];
var p3 = typeof(Test).GetProperty(param);
model.Test = (from tests in model.Test
select tests).
OrderBy(x => p1.GetValue(x, null)).
ThenBy(x => p2.GetValue(x, null)).
ThenBy(x => p3.GetValue(x, null));
but it doesn't works.
i want qry like this
from tests in model.Test
select tests).OrderBy(x => x.lastname).
ThenBy(x => x.firstname).ThenBy(x => x.Title);
order[0]== lastname but how can i use it in the place of OrderBy(x => x.order[0])..?
Thanks in advance.
i solved my case as follows
// list of columns to be used for sorting
List<string>order = Request["orders"].Split(',').ToList();
//map the column string to property
var mapp = new Dictionary<string, Func<Test, string>>
{
{"FirstName", x => x.FirstName},
{"LastName", x => x.LastName},
{"SimpleTitle", x => x.SimpleTitle}
};
//user inputted order
var paras = new List<Func<Test, string>>();
foreach (var para in order)
{
if(!string.IsNullOrEmpty(para))
paras.Add(mapp[para]);
}
//sorting
model.Test= model.Test.OrderBy(paras[0]).ThenBy(paras[1]).ThenBy(paras[2]);
Thanks all,
Actually you are looking for dynamic linq query than you can try out Dynamic LINQ (Part 1: Using the LINQ Dynamic Query Library)
which allow to do like this
it means you can dynamically pass string propertyname to short you collection in orderby function
You can also read about : Dynamic query with Linq
You can compose the expression (any Expression) manually from pieces and then append it to the previous part of query. You can find more info, with example in "Sorting in IQueryable using string as column name".
I'm trying to add a column to the following LINQ expression. I want the column to contain a string concatenation of a text value in a many table called WasteItems. The join would be on "Waste.WasteId = WasteItem.WasteId". My problem is I need to display in a single dynamic column a string such as "EW (5); EX (3)" if there was 8 records in WasteItem and the column containing the 2 character string was called WasteItem.EWC. Hope that makes sense, there must be an efficient way since I realise LINQ is very powerfull. I'm new to it and not sure how to start or go about this:
return from waste in this._db.Wastes
where (from u in _db.UsersToSites.Where(p => p.UserId == userId && p.SystemTypeId == SystemType.W)
select u.SiteId)
.Contains(waste.SiteId)
orderby waste.Entered descending select waste;
THANKS IN ADVANCE
Something like this should do:
wastes.GroupJoin(db.WasteItems, w => w.WastId, wi => wi.WasteId, (w,wi) => new { w, wi })
.AsEnumerable()
.Select(x => new
{
x.w.Name,
Items = string.Join(", ", x.wi.GroupBy(wi => wi.EWC).Select(g => string.Format("{0} ({1})", g.Key, g.Count())))
})
Where wastes is the result from your query. The AsEnumerable() is necessary because Entity Framework can not handle string.Join, so that part must be dealt with in memory.
I could not check the syntax, obviously, but at least it may show you the way to go.
I am new to LINQ, and I wish to convert from one datatype to another in C#, as well as concatenate a string. How would I accomplish this?
For example, what would the SQL statement
SELECT IPv4 = CONVERT(varchar(3), IPv4_octet1) + '.' +
CONVERT(varchar(3), IPv4_octet2) + '.' +
CONVERT(varchar(3), IPv4_octet3) + '.' +
CONVERT(varchar(3), IPv4_octet4) FROM table;
be in LINQ? (The IPv4_octet's are stored as tinyints in the SQL table.)
In this case I suspect you could just write:
var query = data.Select(x => x.IpV4Octet1 + "." +
x.IpV4Octet2 + "." +
x.IpV4Octet3 + "." +
x.IpV4Octet4);
More generally you'd call ToString, e.g.:
// You wouldn't want to actually do this, but...
var query = data.Select(x => x.IpV4Octet1.ToString() + x.IpV4Octet4.ToString());
If you want more control, and you're not using the result in the rest of the query, you may well want to do the formatting on the .NET side - simply use AsEnumerable when you've selected all the information you want from the database, and then do the rest in LINQ to Objects. For example:
var query = db.Select(x => new { x.HostName, x.IpV4Octet1, x.IpV4Octet2,
x.IpV4Octet3, IpV4Octet4 })
.AsEnumerable() // Switch to LINQ to Objects for rest of query
.Select(x => new { x.HostName,
Address = string.Format("{0}.{1}.{2}.{3}"),
x.IpV4Octet1,
x.IpV4Octet2,
x.IpV4Octet3,
x.IpV4Octet4) });
try this:
string ipv4 = string.Join('.',octets.Select(o => o.ToString()).ToArray());