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

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.

Related

Linq to Objects - Left Outer Join Distinct Object Property Values to an Aggregate Count

Lets say I have a generic list of the the following objects:
public class Supermarket
{
public string Brand { get; set; }
public string Suburb { get; set; }
public string State { get; set; }
public string Country { get; set; }
}
So using a List<Supermarket> which is populated with many of these objects with different values I am trying to:
Select the distinct Suburb properties from a
superset of Supermarket objects contained in a List<Supermarket> (say this superset contains 20
distinct Suburbs).
Join the Distinct List of Suburbs above to another set of aggregated and counted Suburbs obtained by a LINQ query to a different, smaller list of List<Supermarket>
The distinct items in my superset are:
"Blackheath"
"Ramsgate"
"Penrith"
"Vaucluse"
"Newtown"
And the results of my aggregate query are:
"Blackheath", 50
"Ramsgate", 30
"Penrith", 10
I want to join them to get
"Blackheath", 50
"Ramsgate", 30
"Penrith", 10
"Vaucluse", 0
"Newtown", 0
Here is what I have tried so far:
var results = from distinctSuburb in AllSupermarkets.Select(x => x.Suburb).Distinct()
select new
{
Suburb = distinctSuburb,
Count = (from item in SomeSupermarkets
group item by item.Suburb into aggr
select new
{
Suburb = aggr.Key,
Count = aggr.Count()
} into merge
where distinctSuburb == merge.Suburb
select merge.Count).DefaultIfEmpty(0)
} into final
select final;
This is the first time I have had to post on Stack Overflow as its such a great resource, but I can't seem to cobble together a solution for this.
Thanks for your time
EDIT: OK So I solved this a short while after the initial post. The only thing I was missing was chaining a call to .ElementAtOrDefault(0) after the call to .DefaultIfEmpty(0). I also verifed that using .First() instead of .DefaultIfEmpty(0) as Ani pointed out worked, The correct query is as follows:
var results = from distinctSuburb in AllSupermarkets.Select(x => x.Suburb).Distinct()
select new
{
Suburb = distinctSuburb,
Count = (from item in SomeSupermarkets
group item by item.Suburb into aggr
select new
{
Suburb = aggr.Key,
Count = aggr.Count()
} into merge
where distinctSuburb == merge.Suburb
select merge.Count).DefaultIfEmpty(0).ElementAtOrDefault(0)
} into final
select final;
LASTLY: I ran Ani's code snippet and confirmed that it ran successfully, so both approaches work and solve the original question.
I don't really understand the assumed equivalence between State and Suburb (where distinctSuburb == merge.State), but you can fix your query adding a .First() after the DefaultIfEmpty(0) call.
But here's how I would write your query: using a GroupJoin:
var results = from distinctSuburb in AllSupermarkets.Select(x => x.Suburb).Distinct()
join item in SomeSupermarkets
on distinctSuburb equals item.Suburb
into suburbGroup
select new
{
Suburb = distinctSuburb,
Count = suburbGroup.Count()
};

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
}

Error: "The xml data type cannot be selected as DISTINCT because it is not comparable."

In my code I have the following Linq Query:
IQueryable<Data> charts = (from report in ctx.Charts group report by new
{
Name = report.ChartTitle.ChartType.ChartCategory.CategoryName,
id = report.ChartTitle.ChartType.ChartCategory.ChartCategoryId,
Period = report.Period
} into d
select new Data
{
Name = d.Key.Name,
Id = d.Key.id,
Period = d.Key.Period,
Reports = from r in d group r by new
{ Title = r.ChartTitle.Name, id = r.ChartTitle.ChartTitleId } into rs
select new Report
{
Title = rs.Key.Title,
Id = rs.Key.id,
Charts = (from c in rs group c by new
{
ChartId = c.ChartId,
FiscalYear = c.FiscalYear,
ModifiedDate = c.ChartView.ModifiedDate,
Function = c.Function.DisplayName,
ChartData=c.ChartView.ViewData
} into cs
select new ChartInfo
{
ChartId = cs.Key.ChartId,
FiscalYear = cs.Key.FiscalYear,
ModifiedDate = cs.Key.ModifiedDate,
Function = cs.Key.Function,
ChartData=cs.Key.ChartData
})
}});
In the above code if I exclude the "ChartData" field (which is of XML datatype), the query executes fine. But when ever I include this field it throws the following error :"The xml data type cannot be selected as DISTINCT because it is not comparable."
Let me know what I am missing here?
You can't group by XML types. This is a SQL restriction, not a LINQ-to-SQL retriction. (See Group by on XML column field with LINQ and select an xml type column in select query with group by SQL Server 2008)
Do you need to group by the XML column? The alternative would be to group by your other columns and then select the first XML value as a result.
Charts = (from c in rs group c by new
{
ChartId = c.ChartId,
FiscalYear = c.FiscalYear,
ModifiedDate = c.ChartView.ModifiedDate,
Function = c.Function.DisplayName,
} into cs
select new ChartInfo
{
ChartId = cs.Key.ChartId,
FiscalYear = cs.Key.FiscalYear,
ModifiedDate = cs.Key.ModifiedDate,
Function = cs.Key.Function,
ChartData=cs.Value.FirstOrDefault().ChartData
})
When using LINQ-to-SQL the items being grouped are still accessible - you don't need to include every 'selected' property / column in the group by` clause like you would in SQL.
You did not tell us what is the actual datatype of the ChartData, but from the error you are describing it looks like the problem is that whatever this datatype is it does not implement the IComparable interface which is a required interface if you want instances of the datatype to be comparable

How to insert row in linq query

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);
);

Resources