SQL Query convert to LINQ - sql-to-linq-conversion

I have SQL Query
SELECT project_id,count(project_id) as vote_count from Votesgroup by project_id;
And how i can write this with LINQ? My LINQ starting code:
private int GetCountOfVotes()
{
using (var db = new SafetyFundDbContext(Options))
{
return db.Votes.Select()
}
}
Sorry, Yes I know question is so stupid, but Im newbie :D .

Don't vote and mark as correct answer.
foreach(var vote in db.Votes.GroupBy(vot => vot.project_id)
.Select(group => new {
ProjectID = group.Key,
Count = group.Count()
})
.OrderBy(x => x.ProjectID)
{
Console.WriteLine("{0} : {1}", vote.ProjectID, vote.Count);
}

Related

Easiest way to check record is exist or not in Linq to Entity Query

in store procedure we can check record is exist or not using following query for fast performance
if EXISTS ( Select 1 from Table_Name where id=#id )
But what about Linq query.
right now i have to store whole data in object like this
UserDetail _U=db.UserDetails.where(x=>x.id==1).FirstOrDefault();
Any Solution?
Use Linq's Any ie bool exist = db.UserDetails.Any(x => x.id == 1);
if(db.UserDetails.Any(x => x.id == 1)) {
var userDetail = db.UserDetails.FirstOrDefault(x => x.id == 1);
}
bool exist = db.UserDetails.Where(x=>x.id==1).Any();
if(exist){
//your-code
}else{
//your-code
}
Just check
if(_U == null)
This way you will get what you want in single query and you not need to execute addition query like
db.UserDetails.Any(x => x.id == 1)
I think, it does not require to fire two query. It can be accomplish by single query.
UserDetails objUserDetails =db.UserDetails.FirstOrDefault(x => x.id == 1);
if(objUserDetails==null)
{
// Do something
}
else
{
// do something with objUserDetails
}
var qry = db.User_Detail.Where(x => x.User_Id == 1).FirstOrDefault();
if(qry !=null)
{
// Do something
}
else
{
return false;
}
Try This...

Raven DB filter on subset of array items and sort on the cheapest of the filter results items

Assuming i have an parent class that I filter on various properties, one of which is a property that is an array of items .
Now say that i want to only return the parent item if my array of items as above a min value and below a max value ...that's fine i can work that bit out;
What if i then want to then sort on the filtered result set of those items
I made a c# fiddle example to show what im trying to achieve :
https://dotnetfiddle.net/mV4d28
(note that foo2 is returned first even though foo1 has items in its array that are less that those in foo2)
As i need to do this using a index i need the index to be able to compute the order by based on the filter criteria used in my query.
I know elasticsearch has an inner hits function that dose this and mongo has pipelines which also dose this so im sure Raven must have a way of doing this too ?
I was hoping using just index and a transform with prams i could achieve this so I tried it:
my index and transform look like this
public class familyTransfrom : AbstractTransformerCreationTask<ParentItem>
{
public class Result : ParentItem{
public double[] ChildItemValuesFiltered { get; set; }
}
public familyTransfrom(){
TransformResults = parents => from parent in parents
let filterMinValue = Convert.ToDouble(ParameterOrDefault("FilterMinValue", Convert.ToDouble(0)).Value<double>())
let filterMaxValue = Convert.ToDouble(ParameterOrDefault("FilterMaxValue", Convert.ToDouble(9999)).Value<double>())
select new Result{
ParentItemId = parent.ParentItemId,
ParentItemName = parent.ParentItemName,
ParentItemValue = parent.ParentItemValue,
//ChildItemValuesFiltered = parent.ChildItems.Where(p => p.ChildItemValues.Any(y => Convert.ToDouble(y) >= Convert.ToDouble(filterMinValue) && Convert.ToDouble(y) <= Convert.ToDouble(filterMaxValue))).SelectMany(t => t.ChildItemValues).ToArray<double>(),
ChildItemValuesFiltered = parent.ChildItems.SelectMany(p => p.ChildItemValues.Where(y => Convert.ToDouble(y) >= Convert.ToDouble(filterMinValue) && Convert.ToDouble(y) <= Convert.ToDouble(filterMaxValue))).ToArray<double>(),
ChildItems = Recurse(parent, x => x.ChildItems).Select(y => y).ToArray()
};
}
}
public class familyIndex : AbstractIndexCreationTask<ParentItem>{
public class Result : ParentItem {
public double[] ChildItemValues { get; set; }
}
public familyIndex(){
Map = parents => from parent in parents
select new Result{
ParentItemId = parent.ParentItemId,
ParentItemName = parent.ParentItemName,
ParentItemValue = parent.ParentItemValue,
ChildItemValues = parent.ChildItems.SelectMany(p => p.ChildItemValues.Select(y => y)).ToArray(),
ChildItems = Recurse(parent, x => x.ChildItems).Select(y => y).ToArray()
};
Index("ParentItemId", FieldIndexing.Analyzed);
Index("ParentItemName", FieldIndexing.Analyzed);
Index("ParentItemValue", FieldIndexing.Analyzed);
Index("ChildItemValues", FieldIndexing.Analyzed);
Index("ChildItems", FieldIndexing.Analyzed);
}
}
my query is as follows , (this is using the live raven playground so this should just work out of the box it you want to use it)
using (IDocumentStore store = new DocumentStore { Url = "http://live-test.ravendb.net/", DefaultDatabase = "altha" })
{
store.Initialize();
using (IDocumentSession session = store.OpenSession())
{
if(1 == 2){
//foreach (ParentItem element in data.OfType<ParentItem>()) {
// session.Store((ParentItem)element);
// session.SaveChanges();
//}
new familyIndex().Execute(store);
new familyTransfrom().Execute(store);
}else{
double filterMinValue = 3.0;
double filterMaxValue = 4.0;
var results = session
.Advanced
.DocumentQuery<familyIndex.Result,familyIndex>()
.WhereBetweenOrEqual("ChildItemValues", filterMinValue, filterMaxValue)
.SetResultTransformer<familyTransfrom, familyTransfrom.Result>()
.SetTransformerParameters(new Dictionary<string, RavenJToken> {
{ "FilterMinValue", filterMinValue },
{ "FilterMaxValue", filterMaxValue } })
.OrderBy("ChildItemValues")
.OfType<ParentItem>().ToList();
results.Dump();
}}
}
What i found was i cant use "ChildItemValuesFiltered" from the transform result as its not index. So unless i can order by the result of a transform ? i couldn't get this to work as although it filters it dosnt order correctly.
Is there another to achieve what i want using projections or intersection or rank or reduce try method ?
I was thinking if i had to perhaps i could use https://ravendb.net/docs/article-page/3.5/csharp/indexes/querying/sorting#custom-sorting
and do something like this:
public class SortByNumberOfCharactersFromEnd : IndexEntriesToComparablesGenerator
{
private readonly double filterMinValue;
private readonly double filterMinValue;
public SortByNumberOfCharactersFromEnd(IndexQuery indexQuery)
: base(indexQuery)
{
filterMinValue = IndexQuery.TransformerParameters["FilterMinValue"].Value<double>(); // using transformer parameters to pass the length explicitly
filterMaxValue = IndexQuery.TransformerParameters["FilterMaxValue"].Value<double>();
}
public override IComparable Generate(IndexReader reader, int doc)
{
var document = reader.Document(doc);
double[] childItemValues = (double[])document.GetValues("ChildItemValuesFiltered").Select(double.Parse).ToArray(); // this field is stored in index
return childItemValues.Where(x => x >= min && x <= max).Min();
}
}
then do a where filter and order by clause using index and transform passing in the same prams that i use in the where filter . however im not sure if this would work ?
More importantly im not sure how i go about getting the sort dll into the plugins ie what name space should the class go under, what name spaces dose it need to import, what assembly name dose it need to use etc
According to https://ravendb.net/docs/article-page/3.5/csharp/server/plugins/what-are-plugins i just need to drop the dll in and raven will this this up , however i cant seem to find what name space i need to reference for IndexEntriesToComparablesGenerator ?
im using linqpad 5 to test my stuff ...so in order to use the custom order i have to reference the class
any tips or advice or how to guild/examples welcome
so it didn't occur to me that i could do the filtering in the transform
TransformResults = parents => from parent in parents
let filterMinValue = Convert.ToDouble(ParameterOrDefault("FilterMinValue", Convert.ToDouble(0)).Value<double>())
let filterMaxValue = Convert.ToDouble(ParameterOrDefault("FilterMaxValue", Convert.ToDouble(9999)).Value<double>())
select new {
ParentItemId = parent.ParentItemId,
ParentItemName = parent.ParentItemName,
ParentItemValue = parent.ParentItemValue,
//ChildItemValuesFiltered = parent.ChildItems.Where(p => p.ChildItemValues.Any(y => Convert.ToDouble(y) >= Convert.ToDouble(filterMinValue) && Convert.ToDouble(y) <= Convert.ToDouble(filterMaxValue))).SelectMany(t => t.ChildItemValues).ToArray<double>(),
ChildItemValuesFiltered = parent.ChildItems.SelectMany(p => p.ChildItemValues.Where(y => Convert.ToDouble(y) >= Convert.ToDouble(filterMinValue) && Convert.ToDouble(y) <= Convert.ToDouble(filterMaxValue))).ToArray<double>(),
ChildItems = Recurse(parent, x => x.ChildItems).Select(y => y).ToArray()
} into r
where r.ChildItemValuesFiltered.Length > 0
orderby r.ChildItemValuesFiltered.Min()
select r;
This gives me what i wanted, here are the sample query:
http://live-test.ravendb.net/databases/altha/indexes/familyIndex?start=0&pageSize=25&resultsTransformer=familyTransfrom&tp-FilterMinValue=3&tp-FilterMaxValue=4
i cant take credit for this as guys at raven helped me but sharing the knowledge for others

Nhibernate Queryover with subquery get Next free number

How can I do this in nHibernate using queryover :
SELECT MIN(t.subid)+1 AS NextID
FROM subject t
WHERE NOT EXISTS
(SELECT id FROM subject n WHERE n.subid=t.subid+1)
Currently I have this but its not working because of this statement "SubId+1"
_session.QueryOver(() => subject)
.WithSubquery
.WhereNotExists(
subject
.Where(x => x.SubId==SubId+1)
.Select(x => x.Id)
)
.Select(Projections.ProjectionList()
.Add(Projections.Min<subject>(x => x.SubId)))
.List().First()
One way, using NOT IN instead of NOT EXISTS (results are the same) would be like this (the SQL query would be a bit different, but result will be the same)
Subjectsubject = null;
Subjectinner = null;
var subquery = QueryOver.Of<Subject>(() => inner)
.Select(Projections.SqlProjection(
// important the subid is the column name, not property name
" subid - 1 as innerId" // the trick here is, that we compare
, new[] { "innerId" } // inner ID - 1, with outer ID
, new IType[] { NHibernateUtil.Int32 }))
;
var id = session.QueryOver(() => subject)
.WithSubquery
.WhereProperty(() => subject.ID)
.NotIn(subquery)
.Select(Projections.ProjectionList().Add(Projections.Min<Subject>(s => s.ID)))
.SingleOrDefault<int>();
var id = id + 1 ; // here we increment in C#, instead of projecting that into SQL
Summary: not sure about algorithm you've used, but the trick how to get "subid - 1" is to use projection:
Projections.SqlProjection(
" subid - 1 as innerId" // sql statement
, new[] { "innerId" } // its alias
, new IType[] { NHibernateUtil.Int32 }) // type is int
NOTE: I would expect the last Projections to be MAX

Remove items from a collection in entity framework

I have a function as below :
IEnumerable<Group> GetAllChildren(int parentID)
{
using (Entities db = new Entities())
{
var result = (from x in db.Groups
where x.ParentID == parentID
select x).ToList();
foreach (Group child in result.ToList())
{
result.AddRange(GetAllChildren(child.GroupID));
}
return result;
}
}
In the above function if I pass a group name I get all the children at all levels.
It works as expected.
Now my query looks like something like :
GroupNamesWithCorrespondingEffects
= new ObservableCollection<GroupNameWithCorrespondingEffect>
(from g in db.Groups
select new GroupNameWithCorrespondingEffect
{
GroupID = g.GroupID,
GroupName = g.GroupName,
CorrespondingEffect = g.Master_Effects.Effect
}
);
The above query will give me all the groups.
Now I want to remove all the groups from GroupNamesWithCorrespondingEffects that are children of a group with id == 25.
I have tried .Remove(GetAllChildren(25)) in 2nd query. but I get following error.
Collection.Remove(GroupNameWithCorrespondingEffect) has some invalid arguments.
hope this help you:
var childs = GetAllChildren(25).ToList();
var childIDList = childs.select(u => u.GroupID).ToList();
GroupNamesWithCorrespondingEffects = GroupNamesWithCorrespondingEffects
.Where(u => !childIDList.Contains(u.GroupID)).ToList();

How do I get row count using the NHibernate QueryOver api?

I'm using the QueryOver api that is part of NHibernate 3.x. I would like to get a row count, but the method I'm using returns all objects and then gets the count of the collection. Is there a way to just return an integer/long value of the number of rows?
I'm currently using:
_session.QueryOver<MyObject>().Future().Count()
After a bit of playing around with the api, this will do it:
_session.QueryOver<MyObject>()
.Select(Projections.RowCount())
.FutureValue<int>()
.Value
If you don't want to return it as a future, you can just get the SingleOrDefault<int>() instead.
Another method
var count = Session.QueryOver<Employer>()
.Where(x => x.EmployerIsActive)
.RowCount();
Another method:
int employerCount = session
.QueryOver<Employer>()
.Where(x => x.EmployerIsActive) // some condition if needed
.Select(Projections.Count<Employer>(x => x.EmployerId))
.SingleOrDefault<int>();
Im using like this:
public int QuantidadeTitulosEmAtraso(Sacado s)
{
TituloDesconto titulo = null;
Sacado sacado = null;
var titulos =
_session
.QueryOver<TituloDesconto>(() => titulo)
.JoinAlias(() => titulo.Sacado, () => sacado)
.Where(() => sacado.Id == s.Id)
.Where(() => titulo.Vencimento <= DateTime.Today)
.RowCount();
}