I need most complicated query - linq

I use Linq to Sql.
I have three table.
tabl_Region: from this table returning .ToList() via county column == 85
tabl_Season: from this table returning .ToList() via startdate >= today
tabl_Desc: from this table returning int [] ID via fldRegion== 1 results && fldSeason== 2 results
I will try to explain not worked codes
TurkusEntities context = new TurkusEntities();
return context.tabl_AttrDesc.Where(c => c.fldRegionId == context.tabl_Region.Where(r => r.fldCounty == 85).ToList() && c.fldSeasonId == context.tabl_Season.Where(s => s.fldStartDate >= DateTime.Now).ToList()).ToList;
I know i can solve it by using loops, but if it is possible i want to use only query.

If you are using Linq2Sql you can get the
sql that is generated by a linq query. with this command.
dc.GetCommand(query).CommandText
If you are using SQL Server Profiler inside the Sql Server (Tools --> SQL Server Profiler)

I found solution but not impossible in one query.
First I got int [] ID arrays which match conditions from two tables.After I wrote a query which provide control column data from arrays.
TurkusEntities context = new TurkusEntities();
Region region = new Region();
string[] dataarray = region.GetAllRegionsBySomeRule(RegionX);
var _db= context.tabl_AttrDesc.Where(c =>dataarray.Contains(c.fldRegionId.ToString().Trim())).ToList();
And Region
public string[] GetAllRegionsBySomeRule(int fldType,int fldRegionX)
{
TurkusEntities context = new TurkusEntities();
var _db = context.tabl_Region.Where(c => c.fldTown.Contains(fldRegionX.ToString())).ToList();
foreach (var data in _db)
{
Regions.Add(data.fldId.ToString().Trim());
}
string[] IDS = Regions.ToArray();
return IDS;
}

Related

IN clause for dates LinQ C# [duplicate]

I need to filter some Entities by various fields using "normal" WHERE and IN clauses in a query over my database, but I do not know how to do that with EF.
This is the approach:
Database table
Licenses
-------------
license INT
number INT
name VARCHAR
...
desired SQL Query in EF
SELECT * FROM Licenses WHERE license = 1 AND number IN (1,2,3,45,99)
EF Code
using (DatabaseEntities db = new DatabaseEntities ())
{
return db.Licenses.Where(
i => i.license == mylicense
// another filter
).ToList();
}
I have tried with ANY and CONTAINS, but I do not know how to do that with EF.
How to do this query in EF?
int[] ids = new int[]{1,2,3,45,99};
using (DatabaseEntities db = new DatabaseEntities ())
{
return db.Licenses.Where(
i => i.license == mylicense
&& ids.Contains(i.number)
).ToList();
}
should work

How do I know if my linq will return a useable object or a null

I am working on a web service. I am using linq to query a database. Seemingly simple, but I've run into an issue. Here is my code for reference:
List<Comment> res = new List<Comment>();
using (ApplicationHistoryEntities ahe = new ApplicationHistoryEntities())
{
res = (from columns in ahe.Comments
where columns.NetforumId == actionuniqueid
select columns).ToList();
}
If I have no entries in the database, will my .ToList() throw an error? I could deploy it, and just try it out but I want to know more about the mechanism that my linq is using. If ahe.Comments database has no rows... what will the (from...) section return?
I could just add a null reference check, use dynamics etc but I want to really understand it.
I found this Q: how to know if my linq query returns null but it seems like all of the answers are in conflict on how it really should be done...
example answers:
Either you can convert it to list and then check the count
Best approach is to check there is null(no items) in list use Any() instead of count()
LINQ queries should never return null and you should not get an exception if the result is empty. You probably have an error in your code.
You can realise the result as a list then check the items.
You can see why I question how it works.
Edit:
Final code looks like this:
List<Comment> res;
using (ApplicationHistoryEntities ahe = new ApplicationHistoryEntities())
{
res = ahe.Comments?.Where(rowItem => rowItem.NetforumId == actionuniqueid).ToList() ??
new List<Comment>().ToList();
}
Look at this example:
List<string> test = new List<string>();
var test1 = test.Where(x => x == "a").ToList();
If test exists but is empty the query returns an empty list. If test is null the query throws an error. So you can adapt the query as follows
List<string> test = new List<string>();
test = null;
var test1 = test?.Where(x => x == "a") ?? new List<string>().ToList();
The query is now 'safe'. Both of the above examples return an empty list i.e. test1.Count() will return zero but will be usable.
You can also look at the definitions of Where and ToList

SPFieldLookupValue in Linq Query

I'm trying to the the value of a lookup field in SharePoint using Linq and a collection of SPListItem - something like this:
int totalDepts = (from SPListItem itm in hourEntries select ((SPFieldLookupValue)itm["Level1"]).LookupValue).Distinct().Count();
But that doesn't seem to work (and it strikes me as missing some steps)
Has anyone done this before?
I wasn't able to figure out to do it directly in the Linq query, so I ended up creating WorkHoursEntries object, and populating it with all my SPListItems
List<WorkHourEntry> workHourEntries = new List<WorkHourEntry>();
foreach (SPListItem hourEntry in hourItems)
{
//Collect entries that are in the current Fiscal Year reporting period
if (fiscalYearMonths.Contains(hourEntry["Reporting_x0020_Month"].ToString()))
{
WorkHourEntry curEntry = new WorkHourEntry();
string Level1 = (string)hourEntry["Level1"];
SPFieldLookupValue val = new SPFieldLookupValue(Level1);
curEntry.organization = val.LookupValue;
SPFieldCalculated cf = (SPFieldCalculated)hourEntry.Fields["WECSCHours"];
curEntry.WECSCHours = cf.GetFieldValueForEdit(hourEntry["WECSCHours"]);
workHourEntries.Add(curEntry);
}
}
This allowed me to run Linq queries directly on the WorkHourEntry collection
var uniqueDeptNames = (from itm in workHourEntries select itm.organization).Distinct().ToArray();

how to use a dynamic variable in orderby clause

am a newbie in linq.. am stuck with one scenario. ie,
i have to sort the search results based on user input.
user inputs are Last Name, First Name and Title. for input 3 drop downs are there and i have to sort result based on the values selected.
i tried
order = Request["orders"].Split(',');
var param = order[0];
var p1 = typeof(Test).GetProperty(param);
param = order[1];
var p2 = typeof(Test).GetProperty(param);
param = order[2];
var p3 = typeof(Test).GetProperty(param);
model.Test = (from tests in model.Test
select tests).
OrderBy(x => p1.GetValue(x, null)).
ThenBy(x => p2.GetValue(x, null)).
ThenBy(x => p3.GetValue(x, null));
but it doesn't works.
i want qry like this
from tests in model.Test
select tests).OrderBy(x => x.lastname).
ThenBy(x => x.firstname).ThenBy(x => x.Title);
order[0]== lastname but how can i use it in the place of OrderBy(x => x.order[0])..?
Thanks in advance.
i solved my case as follows
// list of columns to be used for sorting
List<string>order = Request["orders"].Split(',').ToList();
//map the column string to property
var mapp = new Dictionary<string, Func<Test, string>>
{
{"FirstName", x => x.FirstName},
{"LastName", x => x.LastName},
{"SimpleTitle", x => x.SimpleTitle}
};
//user inputted order
var paras = new List<Func<Test, string>>();
foreach (var para in order)
{
if(!string.IsNullOrEmpty(para))
paras.Add(mapp[para]);
}
//sorting
model.Test= model.Test.OrderBy(paras[0]).ThenBy(paras[1]).ThenBy(paras[2]);
Thanks all,
Actually you are looking for dynamic linq query than you can try out Dynamic LINQ (Part 1: Using the LINQ Dynamic Query Library)
which allow to do like this
it means you can dynamically pass string propertyname to short you collection in orderby function
You can also read about : Dynamic query with Linq
You can compose the expression (any Expression) manually from pieces and then append it to the previous part of query. You can find more info, with example in "Sorting in IQueryable using string as column name".

Row number in LINQ

I have a linq query like this:
var accounts =
from account in context.Accounts
from guranteer in account.Gurantors
where guranteer.GuarantorRegistryId == guranteerRegistryId
select new AccountsReport
{
recordIndex = ?
CreditRegistryId = account.CreditRegistryId,
AccountNumber = account.AccountNo,
}
I want to populate recordIndex with the value of current row number in collection returned by the LINQ. How can I get row number ?
Row number is not supported in linq-to-entities. You must first retrieve records from database without row number and then add row number by linq-to-objects. Something like:
var accounts =
(from account in context.Accounts
from guranteer in account.Gurantors
where guranteer.GuarantorRegistryId == guranteerRegistryId
select new
{
CreditRegistryId = account.CreditRegistryId,
AccountNumber = account.AccountNo,
})
.AsEnumerable() // Moving to linq-to-objects
.Select((r, i) => new AccountReport
{
RecordIndex = i,
CreditRegistryId = r.CreditRegistryId,
AccountNumber = r.AccountNo,
});
LINQ to objects has this builtin for any enumerator:
http://weblogs.asp.net/fmarguerie/archive/2008/11/10/using-the-select-linq-query-operator-with-indexes.aspx
Edit: Although IQueryable supports it too (here and here) it has been mentioned that this does unfortunately not work for LINQ to SQL/Entities.
new []{"aap", "noot", "mies"}
.Select( (element, index) => new { element, index });
Will result in:
{ { element = aap, index = 0 },
{ element = noot, index = 1 },
{ element = mies, index = 2 } }
There are other LINQ Extension methods (like .Where) with the extra index parameter overload
Try using let like this:
int[] ints = new[] { 1, 2, 3, 4, 5 };
int counter = 0;
var result = from i in ints
where i % 2 == 0
let number = ++counter
select new { I = i, Number = number };
foreach (var r in result)
{
Console.WriteLine(r.Number + ": " + r.I);
}
I cannot test it with actual LINQ to SQL or Entity Framework right now. Note that the above code will retain the value of the counter between multiple executions of the query.
If this is not supported with your specific provider you can always foreach (thus forcing the execution of the query) and assign the number manually in code.
Because the query inside the question filters by a single id, I think the answers given wont help out. Ofcourse you can do it all in memory client side, but depending how large the dataset is, and whether network is involved, this could be an issue.
If you need a SQL ROW_NUMBER [..] OVER [..] equivalent, the only way I know is to create a view in your SQL server and query against that.
This Tested and Works:
Amend your code as follows:
int counter = 0;
var accounts =
from account in context.Accounts
from guranteer in account.Gurantors
where guranteer.GuarantorRegistryId == guranteerRegistryId
select new AccountsReport
{
recordIndex = counter++
CreditRegistryId = account.CreditRegistryId,
AccountNumber = account.AccountNo,
}
Hope this helps.. Though its late:)

Resources