A Problem in Linq expression - c#

What is wrong with this code ?
I got this exception on the last line:
Unable to create a constant value of
type
'System.Collections.Generic.IEnumerable`1'.
Only primitive types ('such as Int32,
String, and Guid') are supported in
this context.
var query = from colT in dal.TBL_Gharardad
select colT;
if(lstTarafeGharardadIds.Count>0)
query = from q in query
join id in lstTarafeGharardadIds on q.TarafeGharardadId equals id
select q;
dgvListeGharardad.DataSource = query.ToList();
The lastTarafeGharardadIds is a List<int>
I also test
dgvListeGharardad.DataSource = query;
Everything works well if if expression equals to false and this code
query = from q in query
join id in lstTarafeGharardadIds on q.TarafeGharardadId equals id
select q;
doesn't run. But I can't understand I got the error on the last line (on this code):
dgvListeGharardad.DataSource = query.ToList();

I think linq can't join between an in-memory collection (lstTarafeGharardadIds) and a database table (dal.TBL_Gharardad, dal.v_Gharardad...).
Similar problem: Why won't this LINQ join statement work?
This should work:
var query = (from colT in dal.TBL_Gharardad select colT).AsEnumerable();;
if (lstTarafeGharardadIds.Count>0)
query = from q in query
join id in lstTarafeGharardadIds on q.TarafeGharardadId equals id
select q;
dgvListeGharardad.DataSource = query.ToList();

Wow, thats hard to read!
Anyways, assuming your naming convention is right. you end up with: select colV. Selecting a column results in selecting a IEnumerable rather then a primitive value which your dataSource requires.
You can try and use SelectMany to select the actual value you need
dgvListeGharardad.DataSource = query.SelectMany(x => x.[YourProperty]).ToList();

Related

LINQ join query on Access DB

I have a general understanding issue of Linq as it seems. I tried already to find the answer in other threads but was not successful.
Why does this query not work ? I have two tables: one with customer data, the other with order data and try now to join them. But it fails and I don't understand yet why ? In my opinion it is done as in any other tutorial.
IEnumerable<DataRow> query = from cust_ in Cust.AsEnumerable()
join order_ in Orders.AsEnumerable() on cust_.Field<int>("ID") equals order_.Field<int>("Customer ID")
select new { customer = cust_.Field<string>("LastName") }
This is the error meassge it throws:
Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<<anonymous type: System.Data.DataRow cust_, System.Data.DataRow order_>>' to 'System.Collections.Generic.IEnumerable<System.Data.DataRow>'. An explicit conversion exists (are you missing a cast ?
Your select is not returning a DataRow, it's returning an anonymous type. Either drop the 'new' and return a string,
IEnumerable<string> query = from cust_ in Cust.AsEnumerable()
join order_ in Orders.AsEnumerable() on cust_.Field<int>("ID")
equals order_.Field<int>("Customer ID")
select cust_.Field<string>("LastName")
or maybe better don't specify the type, instead try:
var query = from cust_ in Cust.AsEnumerable()
join order_ in Orders.AsEnumerable() on cust_.Field<int>("ID")
equals order_.Field<int>("Customer ID")
select new { customer = cust_.Field<string>("LastName") }

How to use List<MyTableObject> as a part of LINQ query?

I have this LINQ query:
myDataObject.period = (from pe in myDataObject.myEDMXDataObject.MyTable
join product in myDataObject.products
on pe.ID equals product.ID
where pe.LangID == myDataObject.chosenLang.LangID
select pe).Distinct().ToList();
where myDataObject.products is of type
List<MyDataObject> products;
I get myDataObject.products with a similar LINQ query with join and where clauses, like this
myDataObject.products = (from tbl in MyTableName
join tbl2 in MyTableName2
on tbl1.ID equals tbl2.ID
where /* where conditions here */
select tbl).ToList();
It works properly. But I want to keep my code clean so instead of running all those conditions and the join again, I want to pass the data I have found already into the next LINQ query.
I am getting error like this:
A first chance exception of type 'System.NotSupportedException' occurred in System.Data.Entity.dll
with inner exception:
Unable to create a constant value of type 'MyWPFApp.MyTableName'. Only primitive types or enumeration types are supported in this context.
Of course, the error is clear, I am doing something which is not allowed.
How can I send result from one LINQ query as a part of another LINQ query?
You are using a JOIN when what you should be using is a WHERE:
// select the distinct IDs
var productIds = myDataObject.products.Select(x => x.ID).Distinct().ToList();
myDataObject.period = myDataObject.myEDMXDataObject.MyTable
.Where(pe => pe.LangID == myDataObject.chosenLang.LangID
&& productIds.Contains(pe.ID))
.Distinct()
.ToList();

C# Linq query where Table A column is not equal/doesnt math Table B column join

I have an issue with a c# linq query where I use the != operator, it works well in SQL but when I write the same query in C# it returns a different result, which is the correct way to the the results where table a column doesn't match table b column. Please see my sql query below and then my c# query.
SELECT tba.ID,fa.accountnumber,tba.Account_Number,fa.new_legalname,tba.Legal_Name,fa.new_deliverystatusname, fa.new_deliverystatus,tba.Delivery_Charge
FROM [CRM_Embrace_Integration].[dbo].[CRM_Tarsus_Debtors_Accounts] tba
inner join CRM_MBT_GROUP.dbo.FilteredAccount fa
ON fa.accountnumber collate database_default = tba.Account_Number
where fa.new_legalname collate database_default != tba.Legal_Name
and the Linq query looks like this
var sqlJoinQuery = from accCRM in todaysCRMAccounts
join accSQL in todaysCRMViewAccounts
on accCRM.Account_Number equals accSQL.accountnumber
where accCRM.Legal_Name != accSQL.new_legalname
select new { accCRM.Legal_Name, accSQL.new_legalname };
The SQL query returns the correct result as I want where legal_name(table A) is not equals to legal_name(table B) is the other table.
The Linq query return incorrect result, please assist.
I suggest to try the following Linq as you want the data that aren't in table 2:
var result1 = (from m in db1.Table1
select m).ToList();
var result2 = (from m in db2.Table2
select m).ToList();
var finalResult = (from m in result1
where !(from k in result2
select k.Id).Contains(m.Id)
select m).ToList();
The above will return that aren't in Table2. I hope, this is what you wanted.
Your SQL shows you asking for where they are equal. The LINQ shows you asking for when they are not equal.

Linq Simple query error

I am writing a simple query in LINQ. In fact it is my first query in Linq. How the query is interpreted by compiler confused me. My query is not giving any result.
My Linq Query:
using (DataClasses1DataContext db = new DataClasses1DataContext(("connection string")))
{
var notif_sched_data = from sched in db.NOTIF_SCHEDs
join recip in db.NOTIF_RECIPs
on sched.NOTIF_RECIP_ID equals recip.NOTIF_RECIP_ID
select sched.NOTIF_RPT_ID;
}
which is interpreted by compiler as
SELECT [t0].[NOTIF_RPT_ID]
FROM [dbo].[NOTIF_SCHED] AS [t0]
INNER JOIN [dbo].[NOTIF_RECIP] AS [t1] ON [t0].[NOTIF_RECIP_ID] = [t1].[NOTIF_RECIP_ID]
and it gives no row as output. However,the SQL which is correctly working is :
select [NOTIF_SCHED].[NOTIF_RPT_ID]
from [NOTIF_SCHED]
INNER JOIN [NOTIF_RECIP] on [NOTIF_RECIP].[NOTIF_RECIP_ID]=[NOTIF_SCHED].[NOTIF_RECIP_ID].
Can somebody tell me what I need to change?
if i change the value around equals,it gives error as value is not in the right scope.
You are not materializing the query in anyway. the query will return you IQueryable of what you are selecting there. To get the query actually executed to the database you need to materialize the results with methods like .Count(), .FirstOrDefault(), .Tolist(), etc...
using (var db = new DataClasses1DataContext(("connection string")))
{
var query = (from sched in db.NOTIF_SCHEDs
join recip in db.NOTIF_RECIPs
on sched.NOTIF_RECIP_ID equals recip.NOTIF_RECIP_ID
select sched.NOTIF_RPT_ID);
var count = query.Count();
var list = query.ToList();
}
Thanks for your time. Actually query was correct. The problem was in the class file where we convert sql objects in OOPS objects.
i think the problem is for the last line.you should create a new anonymous type.so changing the last line to this may solve the problem :
select new { sched.NOTIF_RPT_ID };
also you can create a class like this one and set your values to an object of the class
public class data
{
public int id {get;set}
public somthing somthing {get;set}
...
}
now simply :
select new { id = sched.NOTIF_RPT_ID , something = x , ... };

Use Array in Linq query

My question got down voted and put on hold because it is not specific enough. Ill try to specify
Before linq I would do this query
sql="SELECT products.* FROM products INNER JOIN productaccess ON products.id=productaccess.productid"
Now with the entity framework and link I can do this
var products = (from lProducts in db.Products
join lProductAccess in db.ProductAccess on lProducts.ID equals lProductAccess.ProductID
select lProducts).ToList();
But what if I want the flexibilty to get all products or only get the accessible objects
In sql I can do this
sql="SELECT products.* FROM products "
if (useProductAccess) {
sql+=" INNER JOIN productaccess ON products.id=productaccess.productid"
}
In Linq I have to make a separate linq statement.
if (useProductAccess) {
var productsFiltered = (from lProducts in db.Products
join lProductAccess in db.ProductAccess on lProducts.ID equals lProductAccess.ProductID
select lProducts).ToList();
} else {
var productsAll = (from lProducts in db.Products select lProducts).ToList();
}
Now, I could just get all the lProducts and then filter it in an additional linq statement with lProductAccess but then I am using an unnecessary large amount of data.
Is it an option to use:
var productsAccecible = (from lProductAccess in db.ProductAccess where lProductAccess.CustID==custID select lProductAccess).toArray();
var products = (from lProducts in db.Products
where (useProductAccess ?
productsAccessible.Contains(lProducts.ID)
: true)
select lProducts).ToList();
Linq provider will not know how to transform the ternary operator (? and :) in a valid sql, you could try this:
var query = db.Products;
if (useProductAccess)
query = query.Where(p => productsAccessible.Contains(p.ID));
var result = query.ToList();
I used the express profiler to see how the linq statement is translated into sql. It shows that the
productsAccessible.Contains(lProducts.ID)
part gets translated as
products.id in (comma seperated list of values)
My conclusion is it will work fine.
Are there possible drawbacks
Sure - it may produce an inefficient query, or it may not even work.
One thing to note is that your conditional operator won't compile; you can't return a bool and an int from the ternary operator.
Maybe you mean:
var products = (from lProducts in db.Products
where (useProductAccess ?
productsAccessible.Contains(lProducts.ID)
: true)
select lProducts).ToList();
or build your query up using method syntax and only add the where clause if necessary.

Categories