Concatenate Int to String in LINQ Query - c#

I have the following LINQ query.
var providers = from c in Repository.Query<Company>()
where !c.IsDeleted
select new { c.Description, Id = "C" + c.Id };
I'm trying to concatenate the ID to "C". So, for example, if c.Id is 35 then the result should be "C35".
This obviously doesn't work because you can't add an integer (c.Id) to a string. I could easily resolve this in C# using string.Format() or converting the type. But how can I do this in LINQ?

Try using SqlFunctions.StringConvert Method:
var xd = (from c in Repository.Query<Company>()
where !c.IsDeleted
select new { c.Description, Id = "C" + SqlFunctions.StringConvert((double)c.Id).Trim()});

When you need functionality of .NET only in preparing the result (as opposed to, say, filtering, which should be done on RDBMS side to avoid bringing too much data in memory) the common trick is to complete the conversion in memory using the AsEnumerable method:
var providers = Repository.Query<Company>()
.Where(c => !c.IsDeleted)
.Select(c => new { c.Description, c.Id }) // <<== Prepare raw data
.AsEnumerable() // <<== From this point it's LINQ to Object
.Select(c => new { c.Description, Id = "C"+c.Id }); // <<== Construct end result

The code that you have written will work fine. Here is a mock up of the same code and it outputs the Id's
class Company
{
public string Description { get; set; }
public int Id { get; set; }
public bool IsDeleted { get; set; }
}
static void Main()
{
//setup
var list = new List<Company>();
list.Add(new Company
{
Description = "Test",
Id = 35,
IsDeleted = false
});
list.Add(new Company
{
Description = "Test",
Id = 52,
IsDeleted = false
});
list.Add(new Company
{
Description = "Test",
Id = 75,
IsDeleted = true
});
/* code you are looking for */
var providers = from c in list
where !c.IsDeleted
select new { c.Description, Id = "C" + c.Id };
foreach (var provider in providers)
{
Console.WriteLine(provider.Id);
}
Console.ReadKey();
}

What about string format
var providers = from c in Repository.Query<Company>()
where !c.IsDeleted
select new { c.Description, Id = "C" + c.Id.ToString() };

Related

C# - String to list used in Linq Where Any statement

I would like to use this string as a filter to remove some Ids in a linq query
public class ProductKitMakerDto
{
public int Id { get; set; }
public string TitleShort { get; set; }
public string Media { get; set; }
}
[HttpPost]
public ActionResult KitItemSelect(string culture)
{
string productMakerIds = "4174,2196,2201,2460,2508,2204";
//create a list
var productMakerList = new List<ProductKitMakerDto>();
foreach (int i in productMakerIds)
{
productMakerList.Add(new ProductKitMakerDto { Id = i });
}
var itemselects = (from p in _context.Products
where p.Matrix == 2400
select new ProductKitMakerDto()
{
Id = p.Id,
TitleShort = culture == "de" ? p.TitleShortDe :
culture == "fr" ? p.TitleShortFr :
p.TitleShortEn,
Media = "/img/" + p.Photo,
}).ToList();
//From this query I get 40 results.
//Then I want to remove the ones from the list:
//itemselects = itemselects.Where(i => !productMakerList.Any(pml =>pml.Id == i.Id));
//1st (above) I get an Error CS0266 asking for explicit cast. So aplly the modification
itemselects = (List<ProductKitMakerDto>)itemselects.Where(i => !productMakerList.Any(pml =>pml.Id == i.Id));
return Json(itemselects, JsonRequestBehavior.AllowGet);
}
I get 500 (Internal Server Error) - xhr.send( options.hasContent && options.data || null );
I guess the list is empty.
Any idea? Thanks
this does not work
string productMakerIds = "4174,2196,2201,2460,2508,2204";
var productMakerList = new List<ProductKitMakerDto>();
foreach (int i in productMakerIds)
{
productMakerList.Add(new ProductKitMakerDto { Id = i });
}
because you need to split on comma first and parse the string to int:
foreach (string i in productMakerIds.Split(',')) // and parse i to int with int.Parse
but since it's a string literal, initialize it correctly in the first place. Don't use a List<ProductKitMakerDto> because you just need a List<int>, then you can use Contains:
var productMakerList = new List<int>
{
4174, 2196, 2201, 2460, 2508 , 2204
};
you can not cast to a list if it's not a list and Enumerable.Where does not return one:
itemselects = (List<ProductKitMakerDto>)itemselects.Where(i => !productMakerList.Any(pml =>pml.Id == i.Id));
you need to append ToList after the Where
itemselects = itemselects
.Where(i => !productMakerList.Any(pml =>pml.Id == i.Id))
.ToList();
but as mentioned, you could also use this Where before you create that list the first time, so include the condition witha Contains which should be supported:
var itemselects = (from p in _context.Products
where p.Matrix == 2400
&& !productMakerList.Contains(p.Id)
select new ProductKitMakerDto()
{
Id = p.Id,
TitleShort = culture == "de"
? p.TitleShortDe
: culture == "fr" ? p.TitleShortFr : p.TitleShortEn,
Media = "/img/" + p.Photo,
}).ToList();
foreach (string i in productMakerIds.Split(','))
{
productMakerList.Add(new ProductKitMakerDto { Id = int.Parse(i) });
}

JSON File and LINQ Sum and Group

Could I please get some help with querying from a JSON file? Populating a datagrid view works just fine but what I am trying to do now is filter the data using LINQ which I'm really struggling with.
This works just fine, populating the datagridview with all of my jsonfile data
//dataGridView1.DataSource = (from p in movie2
// select p).ToArray();
Below is what I have been playing around with. When I group by employee ID into g, I can not longer use my p references to fields.
using (StreamReader file = File.OpenText(#"C:\temp\GRMReportingJSONfiles\Assigned_FTE\" + myFile))
{
JsonSerializer serializer = new JsonSerializer();
IEnumerable<AssgnData> movie2 = (IEnumerable<AssgnData>)serializer.Deserialize(file, typeof(IEnumerable<AssgnData>));
dataGridView1.DataSource = (from p in movie2
group p by p.EMPLID[0] into g
select new {
EMPLID = p.EMPLID,
(decimal?)decimal.Parse(p.MNTH1) ?? 0).Sum(),
};
);
//dataGridView1.DataSource = (from p in movie2
// select Int32.Parse(p.MNTH1).Sum();
dataGridView1.DataSource = (from p in movie2
group p by p.EMPLID[0] into g
select (decimal?)decimal.Parse(p.MNTH1) ?? 0).Sum(); //dataGridView1.DataSource = (from p in movie2
// select p).ToArray();
//where p.Resource_BU == "7000776"
//chart1.DataBindCrossTable(movie2, "MNTH1", "1", "PROJECT_ID", "Label = FTE");
//chart1.Refresh();
}
Here is part of the array layout, removed other fields for now as I was just trying to focus on these two, dataset has 100k rows and 50 columns
public class AssgnData
{
public string EMPLID { get; set; }
public string MNTH1 { get; set; }
}
In my opinion, using Fluent Syntax usually makes it a bit easier to understand what is going wrong here.
As soon as you group your data you are no longer working on the individual objects, but on a 'group', which is the key and an enumerable of objects.
Getting the sum per employee should then be grouping by the full employee id and then parsing the MNTH1 fields of your objects and summing them.
dataGridView1.DataSource = movie2
.GroupBy(p => p.EMPLID) // create a group of data per employee
.Select(g => new
{
EMPLID = g.Key, // the employee id is the group key
Sum = g.Sum(data => decimal.Parse(data.MNTH1)) // parse and sum
})
.ToArray();
Edit: you are right, you need the ToArray to evaluate the query. I just verified on my computer and it works.
Try following :
class Program
{
static void Main(string[] args)
{
IEnumerable<AssgnData> movie2 = null;
dataGridView1.DataSource = movie2.GroupBy(x => new {id = x.EMPLID, month = x.MNTH1})
.Select(x => new {
EMPLYID = x.Key.id,
MONTH = x.Key.month,
SUM = x.Sum(y => y.value)
});
}
}
public class AssgnData
{
public string EMPLID { get; set; }
public string MNTH1 { get; set; }
public int value { get;set;}
}

How to sort in LINQ If Join other database

Sort in LINQ
I have 2 database CustomerEntities and BillEntities
I want to get CustomerName from CustomerEntities and sort it but it have no data and I want .ToList() just once time because it slow if used many .ToList()
using (var db1 = new CustomerEntities())
{ using (var db2 = new BillEntities())
{
var CustomerData = db1.Customer.Select(s=> new{s.CustomerCode,s.CustomerName}).ToList();
var BillData = (from t1 in db2.Bill
select new {
BillCode = t1.Billcode,
CustomerCode = t1.Customer,
CustomerName = ""; //have no data
});
}
if(sorting.status==true)
{
BillData= BillData.OrderBy(o=>o.CustomerName); //can't sort because CustomerName have no data
}
var data = BillData .Skip(sorting.start).Take(sorting.length).ToList(); // I want .ToList() just once time because it slow if used many .ToList()
foreach (var b in data)
{
var Customer = CustomerData.FirstOrDefault(f => f.CustomerCode==b.CustomerCode );
if(CustomerName>!=null)
{
r.CustomerName = Customer.CustomerName; //loop add data CustomerName
}
}
}
I have no idea to do it. Help me please
I'm not sure if I understand your code but what about this:
var BillData = (from t1 in db2.Bill
select new {
BillCode = t1.Billcode,
CustomerCode = t1.Customer,
CustomerName = db1.Customer.FirstOrDefault(c => c.CustormerCode == t1.Customer)?.CustomerName
});
Then you have objects in BillData that holds the CustomerName and you can order by that:
BillData.OrderBy(bd => bd.CustomerName);
If you just want to get CustomerName from your customer Db and sort it, this is what i would have used. I used orderByDescending but you can use OrderBy aswell.
public List<Customer> getLogsByCustomerName(string customername)
{
using (var dbentites = new CustomerEntities())
{
var result = (from res in dbentites.Customer.OrderByDescending(_ => _.CustomerName)
where res.CustomerName == customername
select res).ToList();
return result.ToList();
}
}

How to join Enum with LINQ Query

I have user table (Default ApplicationUser Table from IdentityUser by ASP.CORE)
and I have added additional field for RoleType. There is also an Enum I added to specify Role Definition.
public enum Roles
{
Administrator = 1,
Headquarters = 2,
Branch = 3,
Driver = 4,
Client = 5
}
Now I want to show all the users in a view as a table along with role description.
I am unable to make LINQ query with Enum & User table using LINQ join.
To get the list of Roles from the enum use:
var roles = Enum.GetValues(typeof(Roles)).Cast<Roles>()
.Select(r => new { Value = (int)r, Name = r.ToString() }).ToList();
you can then use this in your Linq query, for example:
var roles = Enum.GetValues(typeof(Roles)).Cast<Roles>()
.Select(r => new { Value = (int)r, Name = r.ToString() }).ToList();
var users = from u in ApplicationUser
join r in roles on u.Role equals r.Value
select new {Name = u.Name, RoleId = u.Role, RoleDescription = r.Name} ;
A simpler way without the Enum.GetValues is:
var users = from u in ApplicationUser
select new {Name = u.Name, RoleId = u.Role, RoleDescription = (Roles)r.Role.ToString()} ;
var xx = from u in _context.Users
.Select(x => new ApplicationUserList
{ Firstname = x.Firstname,
RoleType = ((Roles)x.RoleId).ToString()
});
// This join is performed in memory
var results =
from e in Enum.GetValues(typeof(Roles)).Cast<Roles>()
join r in ApplicationUser on e equals r.Roles into rs
from r in rs.DefaultIfEmpty()
select new { Roles = e, Count = r?.Count ?? 0};
If I understand your question, you should first convert enum to dictionary an Join between what you need, here is an example:
static void Main(string[] args)
{
ApplicationUser a = new ApplicationUser();
a.userName = "a";
a.role = 1;
ApplicationUser b = new ApplicationUser();
b.userName = "b";
b.role = 3;
List<ApplicationUser> alist=new List<ApplicationUser>();
alist.Add(a);
alist.Add(b);
Dictionary<int, string> DicRoles = new Dictionary<int, string>();
var vals = Enum.GetValues(typeof(Roles));
foreach (var val in vals)
{
DicRoles.Add((int)val, val.ToString());
}
var result = from t in alist
join x in DicRoles on t.role equals x.Key
select new {t.userName,x.Value };
}
public enum Roles:int
{
Administrator = 1,
Headquarters = 2,
Branch = 3,
Driver = 4,
Client = 5
}
}
public class ApplicationUser
{
public string userName { get; set; }
public int role { get; set; }
}

Linq query for group by multiple item

I have a linq query which is working fine.How can i use group by in this query.I need to group by username and itemid and i should get sum(Amount)(All are in table called Carts)
FoodContext db = new FoodContext();
List<CartListing> fd = (from e in db.FoodItems
join o in db.Carts on e.itemid equals o.itemid
where e.itemid == o.itemid
select new CartListing
{
Itemname =e.itemname,
Amount =o.amount,
Price=(float)(e.price*o.amount),
}).ToList();
CartModel vm = new CartModel { CartListings = fd };
I can't see username anywhere in your code example, but to group by Itemname and sum Amount, you would something like:
var grouped = fd.GroupBy(
cl => cl.Itemname,
(key, group) => new CartListing
{
Itemname = key,
Amount = group.Sum(cl => cl.Amount),
Price = group.Sum(cl => cl.Price)
});
To also group by username, just generate a text key containing both values, for instance delimited by a character you know will be contained in neither.
Use:
var grouped = fd.GroupBy((a => new { a.itemid,a.name }) into grp
select new MyClass
{
MyProperty1=grp.key.itemid,
MyProperty2 =grp.Sum(x=>x.whatever)
}
Public MyClass
{
public string MyProperty1 {get;set;}
public int MyProperty2 {get;set;}
}
This way it won't be anonymous

Categories

Resources