In my database I have a join table to store many to many relationships between a JobType and DocumentType (simplified description)
JobType Table
Column
Type
Id
int
Description
varchar(100)
DocumentType Table
Column
Type
Id
int
Description
varchar(100)
JobTypeDocumentType with the following columns:
Column
Type
Id
int
JobType
int
DocumentType
int
I want to retrieve the data from the database and convert the result recordset into an IObservable<collection<ViewModels>>.
In the code below, the GetJobDocumentTypes method returns a collection of JobTypeDocumentType POCOs:
IObservable<IReadOnlyCollection<JobTypeDocumentType>> dataService.GetJobDocumentTypes(int jobTypeId)`
The purpose of getJobTypeDocumenTypeViewModels is to transform the returned POCOs into ViewModels:
private IObservable<IEnumerable<JobTypeDocumentTypeViewModel>> getJobTypeDocumenTypeViewModels(JobType jobType)
{
var result = dataService.GetJobDocumentTypes(jobType.Id)
.Select(items => items.Select(jtdt =>
dataService.GetById<DocumentType>(jtdt.DocumentType_Id)
.Select(dt => new JobTypeDocumentTypeViewModel(jtdt, jobType, dt))));
return result;
}
However, I am stuck with result being of type IObservable<IEnumerable<IObservable<JobTypeDocumentTypeViewModel>>>
Any help and/or suggestions would be appreciated.
You have to use SelectMany in this case:
var result = dataService.GetJobDocumentTypes(jobType.Id)
.SelectMany(items => items
.Select(jtdt => dataService.GetById<DocumentType>(jtdt.DocumentType_Id)
.Select(dt => new JobTypeDocumentTypeViewModel(jtdt, jobType, dt)))
);
Related
i have a table that looks this
TableA
id | data
1 | { "name":"a","dob":"12/12/12" }
2 | { "name":"b","dob":"12/12/13" }
I want to extract the data from 'data' column using JPA such
that i get the data in Hashmap form.My current code is something like this
#Query(value="select data from TableA where id=:id",nativeQuery = true)
String findData(#Param("id") String id );
Then in my main code i call this findData method and convert this string into HashMap like this
String data = daoClass.findData(id);
HashMap<String, Object> map = new Gson().fromJson(data, HashMap.class);
However i am not sure if this is the correct way.
Another issue that i have is from another data table which has schema like this
TableB
id | data
1 | { "name":"a","dob":"12/12/12","class":"BV" }
2 | { "name":"b","dob":"12/12/13","class":"SV" }
From this above table i only require 'name' and 'dob' data from table and save them in
a HashMap.My current code is something like this.
#Query(value="select data->>'name',data->>'dob' from TableB where id=:id,nativeQuery = true)
String findData(#Param("id") String id) ;
I am not sure how will i store the result of this above query in a map form ?
how to get just special 2 attributes from a table to other table( and placement in related textbox) by LINQ??
public string srcht(ACTIVITIES sn)
{
db db = new db();
var q = (from i in db.costumers.Where(i => i.id== sn.id)select i.name).ToList();
return q.Single();
}
public string srcht(ACTIVITIES sn)
{
db db = new db();
var q = (from i in db.costumers.Where(i => i.id== sn.id)select i.family).ToList();
return q.Single();
}
i did linq twice to fill 2 textboxes by name and family in other table. can i do it by one LINQ?
So you have an Activity in sn, and you want the Name and the Family of all Customers that have an Id equal to sn.Id.
var result = db.Customers.Where(customer => customer.Id == sn.Id)
.Select(customer => new
{
Name = customer.Name,
Family = customer.Family,
});
In words: in the database, from the table of Customers, keep only those Customers that have a value for property Id that equals the value of sn.Id. From the remaining Customers select the values of Name and Family.
If you expect that there will only be at utmost one such customer (so if Id is the primary key), just add:
.FirstOrDefault();
If you think there will be several of these customers, add:
.ToList();
The result will be an object, or a list of objects of some anonymous type with two properties: Name and Family.
If you want to mix the Name and the Family in one sequence of strings, which I doubt, consider to put the Name and the Family in an array. Result is sequence of arrays of strings. To make it one array of Strings, use SelectMany:
var result = db.Customers
.Where(customer => customer.Id == sn.Id)
.Select(customer => new string[]
{
customer.Name,
customer.Family,
})
.SelectMany(customer => customer);
Is it possible to create a dynamic selector like the below one in a simple way, and how?
Func<Company, string> companyName = x.CompanyName;
Func<Company, int> companyId = x.CompanyId;
var result = datacontext.Select(x => new
{
CompanyName = companyName,
CompanyId = companyId
});
The above code throws exception: "Unable to create a constant value of type 'System.Func`2... ...Only primitive types or enumeration types are supported in this context."
The problem is that I need to dynamically select up to 8 fields out of possible 50 from approximately 10 different tables, and these fields can be of types string, int, datetime nullable and not nullable. It is quiet difficult to dynamically construct a selector with Expressions. What is the best way to tackle this?
var result = datacontext.Select(x => new
{
CompanyName = mcname(x),
CompanyId = companyId(x)
});
But where is the reason?
Your Funcs should look like this:
Func<Company, string> companyName = (company => company.CompanyName);
Func<Company, int> companyId = (company => company.CompanyId);
To use your func:
var result = datacontext.Select(x => new
{
CompanyName = companyName(x),
CompanyId = companyId(x)
});
I don't know of a way to dynamically create a query for specific fields. You can dynamically chain filters with a single execution though... Unless you're storing a significant amount of information on each row or are loading hundreds of thousands of rows I wouldn't worry about it.
P.S. You'll want to be careful using custom functions in your primary database filters. LINQ can't translate all commands to a native SQL query so it may end up pulling an entire table and filtering in within your code. Just pay attention.
I'm not exactly sure what you are trying to accomplish, but could what you want be done simply like this?
var result = datacontext.Select(x => new
{
CompanyName = x.companyName,
CompanyId = x.companyId
});
I have a table (or entity) named Cases. There is another table CaseStatus_Lookup and the primary key of this table is a foreign key in the Cases table.
What I want to do is: For every status type I want the number of count of cases. For e.g. if status = in progress , I want to know how many cases are in that status.
one other thing: I also want to filter the Cases based on UserID.
I tried several ways in LINQ but could not get vary far. I was wondering if someone could help.
try Linq .GroupBy
am assuming your entity structure
suppose your Case Entity is like
public class Case
{
public int Id{get;set;}
public int CaseStatusId{get;set;}
public int UserId{get;set;}
//navigational fields
public virtual CaseStatus CaseStatus {get;set;}
}
and suppose your CaseStatus entity is like:
public class CaseStatus
{
public int Id{get;set;}
public string Name{get;set;}
//navigational fields..
public virtual ICollection<Case> Cases{get;set;}
}
then you can do this:
using (myDbContext db = new myDbContext())
{
var query = db.Cases.GroupBy(case => case.CaseStatus.Name)
.Select(group =>
new {
Name = group.Key,
Cases= group.OrderBy(x => x.Id),
Count= group.Count()
}
).ToList();
//query will give you count of cases grouped by CaseStatus.
}
similarly you can further filter your result based on userId.
Start to explore about Linq .GroupBy
You need a function that returns the sum and takes the status as parameter :- something like below.
MyCaseStatusEnum caseStatus; //Pass your required status
int caseCount = myCases
.Where(r => r.Status == caseStatus)
.GroupBy(p => p.Status)
.Select(q => q.Count()).FirstOrDefault<int>();
I just started using MS entity framework and have the following problem with LINQ. I will simplify my problem to make it clearer; let's say that I have three tables in SQL Server database:
CustomerData (PK is CustomerId, the table also has some twenty columns to hold customer data).
CustomerData1 (holds some data for the customer in one to one relationship).
CustomerData2 (also holds some data for the customer in one to one relationship).
I know the data with one to one relationship should better be in the same table, but this is some corporate db and it is not possible to alter the original table (so all our data should be in the separate tables).
Now I want to display a list of customer with their data from CustomerData table and add some data columns from CustomerData1 via join.
On the other hand, I want to display a list of customers and add some data from the other table CustomerData2 via join.
So the data is basically the same both times except that in the first case the result includes some columns from CustomerData1 and in the second case some data from CustomerData2 table.
So I created the class Customer with properties for all relevant columns in CustomerData table and added properties for columns that should be included from CustomerData1 and properties that should be included from CustomerData2.
All columns should be included each time, except that when first call will be made the properties that map to CustomerData2 table will be empty and during the second call the properties that map to CustomerData1 table will be empty.
For this I wanted to create one function so I tried to create it like this:
Input parameter in function is whether data from CustomerData1 or CustomerData2 is included.
if (firstList)
{
var query1 = from obj in CustomerData
join rel in CustomerData1
on obj.CustomerId equals rel.CustomerId
select new { obj, rel };
}
if (secondList)
{
var query2 = from obj in CustomerData
join rel in CustomerData2
on obj.CustomerId equals rel.CustomerId
select new { obj, rel };
}
So this code gives me the anonymous type based on the input parameter. Now I want to create Customer objects and order it (order is always the same, it does not depend on input parameter). So I want to create a list of ordered customers and include additional data based on the input parameter.
var query3 = <previous_query_variable>.Select(f => new Customer {
Id = f.obj.CustomerId,
Name = f.obj.CustomerName,
... other columns from Customer table (a lot of them)
//and then add some additional columns based on the input parameter
Data1 = f.rel.someDataFromCustomer1, //only when firstList == true, otherwise empty
Data2 = f.rel.someDataFromCustomer2 //only when secondList == true, otherwise empty
}).OrderBy(f => f.Name); //order by customer name
Of course this does not compile, since both vars are inside if statements. I know I could copy this last statement (var query3 = ...) inside both if statements and include only relevant assignments (Data1 or Data2), but I don't want to assign properties that map to CustomerData table twice (once in both if statements) nor I want to order twice.
How can I solve this problem? I am using .NET 4.
You cannot declare a variable for an anonymous type up-front, i.e. before your two if statements. (Something like var query = null is not supported.) You will have to create a helper type and project into it, like so:
public class ProjectedCustomerData
{
public CustomerData CustomerData { get; set; }
public CustomerData1 CustomerData1 { get; set; }
public CustomerData2 CustomerData2 { get; set; }
}
And then the projection:
IQueryable<ProjectedCustomerData> resultQuery = null;
if (firstList)
{
resultQuery = from obj in CustomerData
join rel in CustomerData1
on obj.CustomerId equals rel.CustomerId
select new ProjectedCustomerData
{
CustomerData = obj,
CustomerData1 = rel
};
}
if (secondList)
{
resultQuery = from obj in CustomerData
join rel in CustomerData2
on obj.CustomerId equals rel.CustomerId
select new ProjectedCustomerData
{
CustomerData = obj,
CustomerData2 = rel
};
}
var query3 = resultQuery.Select(f => new Customer {
Id = f.CustomerData.CustomerId,
Name = f.CustomerData.CustomerName,
// ...
Data1 = f.CustomerData1.someDataFromCustomer1,
Data2 = f.CustomerData2.someDataFromCustomer2
}).OrderBy(f => f.Name);
I am not sure if Customer is an entity in your model or only a class you are using for your projection. If it's an entity you have to change the last code because you cannot project into an entity (basically you would need another helper type for your projection).