How to insert row in linq query - linq

This is my oracle query
select 0 subcatg_cd, 'all' subcatg_name from dual
union
select subcatg_cd,subcatg_name from datacontext.subcatg_mst
order by 1
I want to insert 0 & all at index 0 of the result of second query using linq. I want to achieve it by a single query. How can it be done?

I think best option will be to query rest of the data (second sentence) and then join them on client side.
So:
class Subcat
{
public int subcatg_cd;
public string subcatg_name;
}
then
new Subcat[] { new Subcat() { subcatg_cd = 1, subcatg_name = "All" } }
.Concat(
datacontext.subcatg_mst
.Select(s => new Subcat() { subcatg_cd = s.subcatg_cd, subcatg_name = s.subcatg_name })
.OrderBy(s => s.subcatg);
);

Related

Doing subquery with list of Ids using Dapper 1.50 and Oracle 18

All,
I am sending a list of Ids( More than the max of 1000 allowed by Oracle) in the sql where clause using Dapper 1.50 and Oracle 18. Since there is a limit on the number of items in the in clause, I decided to do a sub query as below but I can't get this to working. Can someone shed some light on this. I will always be sending more than 1000 items as Ids. The second sql statement is not working( It says invalid sql).
public static List<Notes> GetNotes()
{
List<Notes> notes = new List<Notes>();
try
{
using (var connection = OracleConnectionString)
{
connection.Open();
string idCommand = #"select * from (select
id
from
note_text
order by
1
desc)where
rownum <=2000";
var notesList = connection.Query<Notes>(idCommand);
var noteIds1 = notesList .Select(i => i.id).ToList();
string command = #"select
tnt.id as id,
tnt.NOTE_TXT
from
note_text tnt
(
select
note_id
from
dual
where
note_id in :noteIds1
)x where x.note_id = tnt.id";
var info = connection.Query<Notes>(command, new
{
noteIds1
});
notes = info.ToList();
}
}
catch (Exception ex)
{
}
return notes;
}
Where does this list of id's originate? I'd get them into a file that can be accessed as an external table. Then, instead of
select ...
from ...
where id in (<listthatstoolong)
you would
select ...
from ...
where id in (select id from id_external_table)
Then you are not limited to a size of a string of elements in your IN list.

showing multiple rows from database in datagridview using entity framework

I am trying to show multiple records from database in datagridview but I'm having only a single record all the time.
2 tables are involved in this query, from 1st table I acquire all the id's those fulfill the condition and from 2nd table I am getting the user information.
1st table is tblUsers_Roles and 2nd is tblUsers.
These tables have primary/foriegn key relationship.
Here is my code:
IEnumerable<tblUsers_Role> id = db.tblUsers_Role.Where(a => a.User_Role == selectRole);
foreach (var user in id)
{
var userinfo = from b in db.tblUsers
where b.User_Id == user.User_Id
select new { b.First_Name, b.Last_Name, b.Status, b.Authenticated };
dgvResults.DataSource = userinfo.ToList();
dgvResults.Show();
}
You are assigning the grid in the loop. That is not going to work. Maybe something like this will work:
var userinfo =(from ur in db.tblUsers_Role
join u in db.tblUsers
on ur.User_Id equals u.User_Id
where ur.User_Role == selectRole
select new
{
u.First_Name,
u.Last_Name,
u.Status,
u.Authenticated
}).ToList();
dgvResults.DataSource = userinfo;
dgvResults.Show();
Or a alteretive would be like this:
var roles=db.tblUsers_Role
.Where(a => a.User_Role == selectRole)
.Select (a =>a.User_Id).ToList();
var userinfo=
(
from u in db.tblUsers
where roles.Contains(u.User_Id)
select new
{
u.First_Name,
u.Last_Name,
u.Status,
u.Authenticated
}
).ToList();
dgvResults.DataSource = userinfo;
dgvResults.Show();
Not as nice as the first one. But maybe you understand the concept.

grouping a linq statement, doesnt seem to group

I am having a problem trying to group a small linq query.
The query excutes ok however no grouping happens. I assume its due to having 3 different fields I am trying to group.
var data = (from d in All()
group d by new { d.CustomerNumber, d.TransactionAmount, d.CustomerName }
into g
orderby g.Key.CustomerName
select new TransactionViewModel
{
CustomerNumber = g.Key.CustomerNumber,
TransactionAmount = g.Sum(s=>s.TransactionAmount),
CustomerName = g.Key.CustomerName
});
Ideally I would like to be able to return the grouped data with access to the 3 fields.
What do I need to modify?
Are you sure you have to do group d by new { d.CustomerNumber, d.TransactionAmount, d.CustomerName }
I just removed TransactionAmount from group by as it is diffrent for each row.
TRy this.
(from d in All() group d by new { d.CustomerNumber, d.CustomerName } into g orderby g.Key.CustomerName select new Test { CustomerNumber = g.Key.CustomerNumber, TransactionAmount = g.Sum(s => s.TransactionAmount), CustomerName = g.Key.CustomerName });

Linq distinct problem

I am new to using LINQ, right now i have a query in sql with multiple inner joins and it works fine. I am trying to change this to a equivalent LINQ code, i could able to implement LINQ except for the Distinct fact i am using in my query...
my query
select DT.[Name], count(distinct([FeatureControlID])) as [Value], DT.[Weight]
from [DocumentTypes] DT inner join
[DocumentTypesSchema] DTS on
DT.[ID] = DTS.[DocumentTypeID] inner join
ProductsFeaturesControlsDocumentValues [PFCDV] on
DTS.[ID] = PFCDV.[SchemaID]
where [PFCDV].[ProductID] = 72
group by DT.[Name], DT.[Weight], [DT].[ID]
order by [DT].[ID]
and my LINQ without the Distinct condition is as below
from dt in db.DocumentTypes
join dts in db.DocumentTypesSchemas on new { ID = dt.ID } equals new { ID = dts.DocumentTypeID }
join pfcdv in db.ProductsFeaturesControlsDocumentValues on new { ID = dts.ID } equals new { ID = pfcdv.SchemaID }
where
pfcdv.ProductID == 72
group new {dt, pfcdv} by new {
dt.Name,
dt.Weight,
dt.ID
} into g
orderby
g.Key.ID
select new {
g.Key.Name,
Value = (Int64?)g.Count(p => p.pfcdv.FeatureControlID != null),
Weight = (System.Decimal?)g.Key.Weight
}
can anyone give me a hand on this? actually the linq code executes without the Distinct feature i used in the code.
Have you tried something like this?
...
select new {
g.Key.Name,
Value = (Int64?)g.Select(p => p.pfcdv.FeatureControlID)
.Where(id => id != null)
.Distinct().Count()
Weight = (System.Decimal?)g.Key.Weight
}

Multiple "order by" in LINQ

I have two tables, movies and categories, and I want to get an ordered list by categoryID first and then by Name.
The movie table has three columns ID, Name and CategoryID.
The category table has two columns ID and Name.
I tried something like the following, but it didn't work.
var movies = _db.Movies.OrderBy( m => { m.CategoryID, m.Name })
This should work for you:
var movies = _db.Movies.OrderBy(c => c.Category).ThenBy(n => n.Name)
Using non-lambda, query-syntax LINQ, you can do this:
var movies = from row in _db.Movies
orderby row.Category, row.Name
select row;
[EDIT to address comment] To control the sort order, use the keywords ascending (which is the default and therefore not particularly useful) or descending, like so:
var movies = from row in _db.Movies
orderby row.Category descending, row.Name
select row;
Add "new":
var movies = _db.Movies.OrderBy( m => new { m.CategoryID, m.Name })
That works on my box. It does return something that can be used to sort. It returns an object with two values.
Similar, but different to sorting by a combined column, as follows.
var movies = _db.Movies.OrderBy( m => (m.CategoryID.ToString() + m.Name))
Use the following line on your DataContext to log the SQL activity on the DataContext to the console - then you can see exactly what your LINQ statements are requesting from the database:
_db.Log = Console.Out
The following LINQ statements:
var movies = from row in _db.Movies
orderby row.CategoryID, row.Name
select row;
AND
var movies = _db.Movies.OrderBy(m => m.CategoryID).ThenBy(m => m.Name);
produce the following SQL:
SELECT [t0].ID, [t0].[Name], [t0].CategoryID
FROM [dbo].[Movies] as [t0]
ORDER BY [t0].CategoryID, [t0].[Name]
Whereas, repeating an OrderBy in LINQ, appears to reverse the resulting SQL output:
var movies = from row in _db.Movies
orderby row.CategoryID
orderby row.Name
select row;
AND
var movies = _db.Movies.OrderBy(m => m.CategoryID).OrderBy(m => m.Name);
produce the following SQL (Name and CategoryId are switched):
SELECT [t0].ID, [t0].[Name], [t0].CategoryID
FROM [dbo].[Movies] as [t0]
ORDER BY [t0].[Name], [t0].CategoryID
I have created some extension methods (below) so you don't have to worry if an IQueryable is already ordered or not. If you want to order by multiple properties just do it as follows:
// We do not have to care if the queryable is already sorted or not.
// The order of the Smart* calls defines the order priority
queryable.SmartOrderBy(i => i.Property1).SmartOrderByDescending(i => i.Property2);
This is especially helpful if you create the ordering dynamically, f.e. from a list of properties to sort.
public static class IQueryableExtension
{
public static bool IsOrdered<T>(this IQueryable<T> queryable) {
if(queryable == null) {
throw new ArgumentNullException("queryable");
}
return queryable.Expression.Type == typeof(IOrderedQueryable<T>);
}
public static IQueryable<T> SmartOrderBy<T, TKey>(this IQueryable<T> queryable, Expression<Func<T, TKey>> keySelector) {
if(queryable.IsOrdered()) {
var orderedQuery = queryable as IOrderedQueryable<T>;
return orderedQuery.ThenBy(keySelector);
} else {
return queryable.OrderBy(keySelector);
}
}
public static IQueryable<T> SmartOrderByDescending<T, TKey>(this IQueryable<T> queryable, Expression<Func<T, TKey>> keySelector) {
if(queryable.IsOrdered()) {
var orderedQuery = queryable as IOrderedQueryable<T>;
return orderedQuery.ThenByDescending(keySelector);
} else {
return queryable.OrderByDescending(keySelector);
}
}
}
There is at least one more way to do this using LINQ, although not the easiest.
You can do it by using the OrberBy() method that uses an IComparer. First you need to
implement an IComparer for the Movie class like this:
public class MovieComparer : IComparer<Movie>
{
public int Compare(Movie x, Movie y)
{
if (x.CategoryId == y.CategoryId)
{
return x.Name.CompareTo(y.Name);
}
else
{
return x.CategoryId.CompareTo(y.CategoryId);
}
}
}
Then you can order the movies with the following syntax:
var movies = _db.Movies.OrderBy(item => item, new MovieComparer());
If you need to switch the ordering to descending for one of the items just switch the x and y inside the Compare()
method of the MovieComparer accordingly.
If use generic repository
> lstModule = _ModuleRepository.GetAll().OrderBy(x => new { x.Level,
> x.Rank}).ToList();
else
> _db.Module.Where(x=> ......).OrderBy(x => new { x.Level, x.Rank}).ToList();

Resources