C#, JSON: Join two array to use JSON - c#

Can you help me to resolve this proplem. I will use JSON with Name and Description and want to merge two array.
var listCateogries = categories.Select(x => new
{
Name = x.Name,
Description = x.Description
});
var listProducts = products.Select(x => new
{
Name = x.Name,
Description = x.Details
});
var data = listCateogries + listProducts;
Thanks you very much.

Try Enumerable.Concat
var data = listCateogries.Concat(listProducts);

Related

C# LinqToExcel, Distinct showing all results - tried online solutions, couldn't solve

var ItemMaster = new ExcelQueryFactory("E:\\Group Item Master.xlsx");
var ItemList = (from x in ItemMaster.Worksheet()
select new
{
CategoryName = x["CategoryName"],
GroupName = x["GroupName"],
ModelNo = x["ModelNo"],
Description = x["Description"],
Code = x["Code"]
}).ToList();
var DistinctCategory = ItemList.Select(x => x.CategoryName).ToArray().Distinct();
//shows categoryname repeated
var iteml = ItemList.GroupBy(x => x.CategoryName);
var DistinctCategoryTwo = iteml.Select(x => x.First()).ToList();
//shows categoryname repeated
Sorry guys, it was linqToExcel specific issue
var CategoryList = ItemList.Select(x => x.CategoryName.Value).Distinct().ToList();
value column was needed to fix it

Entity Framework: How to query a number of related tables in a database making a single trip

I have a query that is currently far too slow.
I am trying to search a Code (a string) on the main page that will bring the user the relevant info.
Eg. The user can search a code from the main page and this will search for the code in Job, Work Phase, Wbs, Work Element, EA, Jobcard and Estimate and return the relevant info.
I make a number of trips to the database to collect the data i need when I believe it can be done in just one.
I have a number of tables that are all linked:
Contracts, Jobs, WorkPhases, Wbss, Engineering Activities, Jobcards and Estimates.
Contracts have a list of Jobs,
Jobs have a list of Workphases,
Workphases have a list of Wbss etc
Is there a quicker way to do this?
public Result Handle(Query query)
{
query.Code = query.Code ?? string.Empty;
var result = new Result();
//result.SetParametersFromPagedQuery(query);
result.Items = new List<Item>();
if (query.SearchPerformed)
{
var contracts = _db.Contracts.AsEnumerable().Where(x => x.Code == query.Code);
result.Items = result.Items.Concat(contracts.Select(x => new Item()
{
Code = x.Code,
Id = x.Id,
Name = x.Name,
Type = MainPageSearchEnum.Contract,
ContractName = x.Name,
Url = string.Format("Admin/Contract/Edit/{0}", x.Id)
})).ToList();
var jobs = _db.Jobs.AsEnumerable().Where(x => x.Code == query.Code);
result.Items = result.Items.Concat(jobs.Select(x => new Item()
{
Code = x.Code,
Id = x.Id,
Name = x.Name,
ContractName = x.Contract.Name,
Type = MainPageSearchEnum.Job,
Url = string.Format("Admin/Job/Edit/{0}", x.Id)
})).ToList();
//var workPhases = _db.WorkPhases.AsEnumerable().Where(x => x.ContractPhase.Code.ToLower() == query.Code.ToLower());
var workPhases = _db.WorkPhases.AsEnumerable().Where(x => x.ContractPhase.Code == query.Code);
result.Items = result.Items.Concat(workPhases.Select(x => new Item()
{
Code = x.ContractPhase.Code,
Id = x.Id,
Name = x.ContractPhase.Name,
Type = MainPageSearchEnum.WorkPhase,
Url = string.Format("Admin/WorkPhase/Edit/{0}", x.Id)
})).ToList();
var wbss = _db.WBSs.AsEnumerable().Where(x => x.Code == query.Code);
result.Items = result.Items.Concat(wbss.Select(x => new Item()
{
Code = x.Code,
Id = x.Id,
Name = x.Name,
Type = MainPageSearchEnum.WBS,
Url = string.Format("Admin/WBS/Edit/{0}", x.Id)
})).ToList();
var eas = _db.EngineeringActivities.AsEnumerable().Where(x => x.Code == query.Code);
result.Items = result.Items.Concat(eas.Select(x => new Item()
{
Code = x.Code,
Id = x.Id,
Name = x.Name,
Type = MainPageSearchEnum.EA,
Url = string.Format("Admin/EngineeringActivity/Edit/{0}", x.Id)
})).ToList();
var jcs = _db.Jobcards.AsEnumerable().Where(x => x.Code == query.Code);
result.Items = result.Items.Concat(jcs.Select(x => new Item()
{
Code = x.Code,
Id = x.Id,
Name = x.Name,
Type = MainPageSearchEnum.EA,
Url = string.Format("Admin/JobCard/Edit/{0}", x.Id)
})).ToList();
var estimates = _db.Estimates.AsEnumerable().Where(x => x.Code == query.Code);
result.Items = result.Items.Concat(estimates.Select(x => new Item()
{
Code = x.Code,
Id = x.Id,
Name = x.Name,
Type = MainPageSearchEnum.Estimate,
Url = string.Format("Estimation/Estimate/Edit/{0}", x.Id)
})).ToList();
}
return result;
}
Disclaimer: I'm the owner of the project Entity Framework Plus
This library has a Query Future feature which allows batching multiple queries in a single roundtrip.
Example:
// using Z.EntityFramework.Plus; // Don't forget to include this.
var ctx = new EntitiesContext();
// CREATE a pending list of future queries
var futureCountries = ctx.Countries.Where(x => x.IsActive).Future();
var futureStates = ctx.States.Where(x => x.IsActive).Future();
// TRIGGER all pending queries in one database round trip
// SELECT * FROM Country WHERE IsActive = true;
// SELECT * FROM State WHERE IsActive = true
var countries = futureCountries.ToList();
// futureStates is already resolved and contains the result
var states = futureStates.ToList();
Wiki: EF+ Query Future
Have you tried the Union / UnionAll operator?
It's purpose is exactly like you wish - combine the identical data from different sources.
Furthermore due to the concept of deferred execution your query will only be executed when you actually iterate over the result (or call a method that does that, for example - .ToList()
var contractsQuery = _db.Contracts.AsEnumerable().Where(x => x.Code == query.Code).Select(x=>new {Code=x.Code, Id=x.Id, ...});
var jobsQuery = _db.Jobs.AsEnumerable().Where(x => x.Code == query.Code).Select(x=>new{Code=x.Code, Id=x.Id, ...});
var workPhasesQuery = _db.WorkPhases.AsEnumerable().Where(x => x.ContractPhase.Code == query.Code).Select(x=>new{Code=x.Code, Id=x.Id, ...});
// and so on
var combinedQuery = contractsQuery.UnionAll(jobsQuery).UnionAll(workPhasesQuery ).UnionAll(...
var result = combinedQuery.ToList();
A similar question is Union in linq entity framework
Another code sample can be found here
Please notice that this is exactly the same concept of manipulating data as in T-SQL union, and under the covers you will get an sql query using a union operator
Yes there most certainly is a way to query multiple tables. You can use the Include() method extension for your query. for instance:
var examplelist = _db.Contracts.(v => v.id == "someid" && v.name == "anotherfilter").Include("theOtherTablesName").ToList();
You can include as many tables as you like this way. This is the recommended method.
You can also use the UnionAll() method but you'd have to define your queries separately for this

Linq query rewriting

This has really stumped me...
I have two queries..
This one does NOT work, with the error,
"LINQ to Entities does not recognize the method GetAllCustomers()' method, and this method cannot be translated into a store expression."
results = theDocuments.Select(x => new DocumentModel()
{
document_id = x.document_id,
document_type = x.document_type,
franchisee_id = x.franchisee_id,
customer_id = x.customer_id,
address = x.address,
area_id = x.area_id,
***HERE***customer_name = outletService.GetAllCustomers().Where(xx => xx.id == x.customer_id).First().name
}).OrderBy(x => x.document_id);
Now rewriting it like this works:
results = from p in theDocuments
join cust in outletService.GetAllCustomers() on p.customer_id equals cust.id
select new DocumentModel()
{
customer_name = cust.name,
document_id = p.document_id,
document_type = p.document_type,
franchisee_id = p.franchisee_id,
customer_id = p.customer_id,
address = p.address
};
I understand that this cannot be converted to it's relevant SQL, however, I am not sure what the second query is doing differently in it's execution in order for it to work, does it execute the GetAllCustomers() before doing anything else? How is it working differently internally?
How could I rewrite the first query so that it executes correctly?
Thanks,
James.
**This is what I ended up with **
results = theDocuments.Join(
outletService.GetAllCustomers(), docs => docs.customer_id, customers => customers.id, (doc, cust) => new DocumentModel()
{
document_id = doc.document_id,
document_type = doc.document_type,
franchisee_id = doc.franchisee_id,
customer_id = doc.customer_id,
address = doc.address,
area_id = doc.area_id,
customer_name = cust.name
});
The first one try to translate your method into a SQL method, the second create a join in the query. In my opinion the correct way is using join :)
I was a problem. I found a solution. That might be help you.
dynamic user = new
{
Name = "",
Surname = ""
};
dynamic userModel = new
{
Name = "",
Surname = "",
FullName = ""
};
var query = db.User.AsNoTracking();
query = query.Select(x => new userModel
{
Name = x.Name,
Surname = x.SurName,
FullName = $"{x.Name}{x.SurName}",
}).ToList();
If you try to execute this query. You will take a crash. Linq doesnt support
FullName = $"{x.Name}{x.SurName}"
You have to change this line to
FullName = x.Name + " " + x.SurName

Add a List<object> into an object.Array

I have a simple way to put 2 known profiles in my profileArray list as shown below:
Parameters params = new Parameters();
params.plist = new Plist();
params.plist.profileArray = new[]
{
new Profile{name = "john", age = 12, country = "USA"},
new Profile{name = "Brad", age = 20, country = "USA"}
};
Now i have a
List<Profiles> UserProfiles
which has a bunch of profiles in it.
How do i add this list to params.plist.profileArray?
Any help is appreciated.
Thanks.
This is what is in UserProfile:
List<Profiles> UserProfiles
foreach(Profiles userProfile in UserProfiles)
{
string name = userProfile.Name;
string age = userProfile.Age;
string country = userProfile.Country;
string sex = userProfile.Sex;
string isMarried = userProfile.IsMarried;
}
You can use Enumerable.ToArray:
params.plist.profileArray = UserProfiles.ToArray();
If you want to add the list to the array, an array cannot be modified, you have to create a new one, for example by using Enumerable.Concat:
var newProfile = params.plist.profileArray.Concat(UserProfiles);
params.plist.profileArray = newProfile.ToArray();
Since these are two different classes with similar properties:
var profiles = UserProfiles
.Select(up => new Profile{name = up.Name, age = up.Age, country = up.Country});
var newProfile = params.plist.profileArray.Concat(profiles);
params.plist.profileArray = newProfile.ToArray();
Try this:
params.plist.profileArray = UserProfiles.ToArray();
How about this?
params.plist.profileArray =
UserProfiles
.Select(up => new
{
name = up.Name,
age = up.Age,
country = up.Country,
})
.ToArray();
Try
params.plist.profileArray = params
.plist
.profileArray
.Concat( UserProfiles )
.ToArray()
;
Since you're using an array (and arrays in C# are of fixed size), you'l need to create a new array with the combined data.
There are several ways to do this, the simplest would probably be something like this:
var newList = new List<Profile>();
newList.AddRange(params.plist.profileArray);
newList.AddRange(UserProfiles);
params.plist.profileArray = newList.ToArray();
If can you change the implementation of Plist, I would recommend changing the array to a List<Profile>. Then the code would look like this instead:
params.plist.profileArray.AddRange(UserProfiles);

LINQ Sorting List<T> based on string Name property

I have the following:
public void ProcessRequest(HttpContext context)
{
string query = context.Request.QueryString["term"];
System.Web.Script.Serialization.JavaScriptSerializer JsonSerializer =
new System.Web.Script.Serialization.JavaScriptSerializer();
List<Category> Categs = Category.getAll();
var result = from c in Categs where Categs.Contains(c.Name) select c;
context.Response.ContentType = "application/json";
context.Response.Write(JsonSerializer.Serialize(result));
}
Trying to return a list of [ { label: "Choice1", value: "value1" }, ... ] for jQuery UI autocomplete. I have Categories which have ID and Name properties and I want to filter the List based on the "term" in the querystring and Name property. How should i do that?
Thanks in advance.
If your end goal is making that list of [ { label: "Choice1", value: "value1" }, ... ] and have it sorted by name, then this should work:
result
.OrderBy(x => x.Name)
.Select(x => new { label: x.Name, value: x.Id }); // create an anonymous type
Edit: Your current query:
var result = from c in Categs where Categs.Contains(c.Name) select c;
Looks wrong. I think that query is the same as just selecting all Categs. If you want to query based on the term they sent, replace c.Name with query in that linq expression:
var result = from c in Categs where Categs.Contains(query) select c;
string upperTerm = term.ToUpper();
var result = Category.getAll()
.Where(c => c.Name.ToUpper().Contains(upperTerm))
.Select(c => new { label = c.Name, value = c.Id });
Then JSON serialize result.

Categories