converting int to string in linq to entites - c#

My Code is :
var currency = (from ac in db.shop
join cur in db.books
on ac.CODE equals cur.CODE.ToString() //here is the Error
// because "ac.code is type strig" & "cur.code is type long
where ac.ID == merchantId
select new Currency()
{
ShopCode = ac.CODE,
PosCode = ac.POSCODE,
}).ToList();
I found that .ToString(), SqlFunctions.StringConvert(long) are not working in the join query conditions but working in 'select' area in the query.
However Devart.Data.Oracle.Entity.OracleFunctions.ToChar((long)cur.CODE) is working fine. Since I am using entity framework it shouldn't have problems with particular DB types (i.e. oracle or sql server). It should work even I change from oracle to sql in future.
Please give me a solution for this.

Did you try casting on this.
Try : ac.CODE equals (string)cur.CODE

You can create a VIEW Currency on the database and perform the query on the view.
Here is the list of supported method for Linq to Entities, if conversion is not supported you can not execute it.
http://msdn.microsoft.com/en-us/library/bb738681.aspx

The problem is, that EF is trying to convert whole your expression into T-SQL query.
So it will look similar to this:
select ac.CODE, cur.CODE from shop ac
inner join books cur on ac.CODE = cur.CODE
Here is your problem. CODE fields have diffent types and server can't join on them.
In T-SQL you can use CAST, but since EF don't support such operation you can't do anything.
And afterall, why do you store those codes in string? If you have such a query, then in most cases there is some problem with your DB schema.
I would suggest you to look at the schema and refactor it, so CODE is always of type long. Then everything will work.
If you still really want to use different types for you columns. You can look at this question, to see how to execute CAST Convert String to Int in EF 4.0

this should solve your problem:
var currency = (from ac in db.shop
join cur in db.books
let codestr = cur.CODE.ToString()
on ac.CODE equals codestr
where ac.ID == merchantId
select new Currency()
{
ShopCode = ac.CODE,
PosCode = ac.POSCODE,
}).ToList();

Related

Dynamics CRM: Problem with Composite Key Join in LINQ

I have following query in LINQ to LEFT JOIN same entity:
query = from a in orgSvcContext.CreateQuery("entity1")
join b in orgSvcContext.CreateQuery("entity1")
on new { v1 = a["field1"], v2 = a["field2"] } equals new { v1 = b["field2"], v2 = b["field1"] } into gr
from c_joined in gr.DefaultIfEmpty()
where c_joined["field0"] == null && (a["field1"].Equals(new Guid(#param)) || a["field2"].Equals(new Guid(#param)))
select a;
It complains the following error:
invalid 'join' condition. an entity member is invoking an invalid
property or method
I refer from here: https://learn.microsoft.com/en-us/dotnet/csharp/linq/join-by-using-composite-keys
Anything wrong with my JOIN? I have no problem if I just use
on a["field1"] equals b["field2"]
Thanks in advance.
The new { v1 = a["field1"], v2 = a["field2"] } construct cannot be resolved to an attribute name.
The LINQ implementation for Dynamics CRM is very limited as it attempts to convert LINQ expressions into QueryExpression queries. These queries in turn only implement a basic subset of the SQL language.
When joining two entities make shure that after the on the left and right side can be resolved to existing lookup attributes of both entities.
Still keep in mind not all QueryExpression capabilities can be used in LINQ queries.

Multiple joins with multiple on statements using Linq Lambda expressions [duplicate]

Suppose I have a list of {City, State}. It originally came from the database, and I have LocationID, but by now I loaded it into memory. Suppose I also have a table of fast food restaurants that has City and State as part of the record. I need to get a list of establishments that match city and state.
NOTE: I try to describe a simplified scenario; my business domain is completely different.
I came up with the following LINQ solution:
var establishments = from r in restaurants
from l in locations
where l.LocationId == id &&
l.City == r.City &&
l.State == r.State
select r
and I feel there must be something better. For starters, I already have City/State in memory - so to go back to the database only to have a join seems very inefficient. I am looking for some way to say {r.City, r.State} match Any(MyList) where MyList is my collection of City/State.
UPDATE
I tried to update based on suggestion below:
List<CityState> myCityStates = ...;
var establishments =
from r in restaurants
join l in myCityStates
on new { r.City, r.State } equals new { l.City, l.State } into gls
select r;
and I got the following compile error:
Error CS1941 The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'Join'.
UPDATE 2
Compiler didn't like anonymous class in the join. I made it explicit and it stopped complaining. I'll see if it actually works in the morning...
It seems to me that you need this:
var establishments =
from r in restaurants
join l in locations.Where(x => x.LocationId == id)
on new { r.City, r.State } equals new { l.City, l.State } into gls
select r;
Well, there isn't a lot more that you can do, as long as you rely on a table lookup, the only thing you can do to speed up things is to put an index on City and State.
The linq statement has to translate into a valid SQL Statement, where "Any" would translate to something like :
SELECT * FROM Restaurants where City in ('...all cities')
I dont know if other ORM's give better performance for these types of scenarios that EF, but it might be worth investigating. EF has never had a rumor for being fast on reads.
Edit: You can also do this:
List<string> names = new List { "John", "Max", "Pete" };
bool has = customers.Any(cus => names.Contains(cus.FirstName));
this will produce the necessary IN('value1', 'value2' ...) functionality that you were looking for

Join vs Navigation property for sub lists in Entity Framework

I have a sql statement like this:
DECLARE #destinations table(destinationId int)
INSERT INTO #destinations
VALUES (414),(416)
SELECT *
FROM GroupOrder grp (NOLOCK)
JOIN DestinationGroupItem destItem (NOLOCK)
ON destItem.GroupOrderId = grp.GroupOrderId
JOIN #destinations dests
ON destItem.DestinationId = dests.destinationId
WHERE OrderId = 5662
I am using entity framework and I am having a hard time getting this query into Linq. (The only reason I wrote the query above was to help me conceptualize what I was looking for.)
I have an IQueryable of GroupOrder entities and a List of integers that are my destinations.
After looking at this I realize that I can probably just do two joins (like my SQL query) and get to what I want.
But it seems a bit odd to do that because a GroupOrder object already has a list of DestinationGroupItem objects on it.
I am a bit confused how to use the Navigation property on the GroupOrder when I have an IQueryable listing of GroupOrders.
Also, if possible, I would like to do this in one trip to the database. (I think I could do a few foreach loops to get this done, but it would not be as efficient as a single IQueryable run to the database.)
NOTE: I prefer fluent linq syntax over the query linq syntax. But beggars can't be choosers so I will take whatever I can get.
If you already have the DestinationGroupItem as a Navigation-property, then you already have your SQL-JOIN equivalent - example. Load the related entities with Include. Use List's Contains extension method to see if the desired DestinationId(s) is(are) hit:
var destinations = new List<int> { 414, 416 };
var query = from order in GroupOrder.Include(o => o.DestinationGroupItem) // this is the join via the navigation property
where order.OrderId == 5662 && destinations.Contain(order.DestinationGroupItem.DestinationId)
select order;
// OR
var query = dataContext.GroupOrder
.Include(o => o.DestinationGroupItem)
.Where(order => order.OrderId == 5662 && destinations.Contain(order.DestinationGroupItem.DestinationId));

join using lambda expressions and retrieving the data

I have a members table with columns
member_Id,
member_Lastname,
member_Firstname,
member_Postcode,
member_Reference,
member_CardNum,
and i have another table mshipoptions with columns
mshipoption_id
mshiptype_id
and i have another table mshiptypes
mshiptype_id
mshiptype_name
another table memtomship
memtomship_id
mshipoption_id
member_id
and my entity name is eclipse
at the form load i am filling the datagrid view by using the below method....
private void reportmembers()
{
MemberControlHelper.Fillmembershiptypes(cbGEMembershiptype);
var membersreport = from tsgentity in eclipse.members
join memtomships in eclipse.membertomships on tsgentity.member_Id equals memtomships.member_Id
join mshipoptiions in eclipse.mshipoptions on memtomships.mshipOption_Id equals mshipoptiions.mshipOption_Id
join mshiptypes in eclipse.mshiptypes on mshipoptiions.mshipType_Id equals mshiptypes.mshipType_Id
select
new {
tsgentity.member_Id,
tsgentity.member_Lastname,
tsgentity.member_Firstname,
tsgentity.member_Postcode,
tsgentity.member_Reference,
tsgentity.member_CardNum,
mshiptypes.mshipType_Name,
};
if (txtfirstname.Text != "")
{
dgvmembersrep.DataSource = membersreport.Where(t => t.member_Firstname == txtlastname.Text).ToList();
}
if (txtcardnum.Text != "")
{
dgvmembersrep.DataSource = membersreport.Where(a => a.member_CardNum == txtcardnum.Text).ToList();
}
}
that was fine,...
My problem is here , i have one comboboxsay (cbgemembershiptype)......
when ever the user select the membership type in (cbgemembershiptype) i want retrieve the details of members those who have that membership type....
(Your question is unclear in terms of whether the query you've got already does what you want. I'm assuming it does.)
It's unclear why you'd want to convert this query into one using lambda expressions. It's certainly possible, but each join would introduce a new range variable - by the end, the strictly literal translation would end up with a select involving something like
member_Id = a.b.c.member_Id
... it wouldn't be very readable at all.
There are ways of improving it if you're writing it out by hand, but it still wouldn't be as clear as the query expression.
You should definitely know both forms, and write using whichever form is clearest for the query in question - which in this case is definitely the query expression form.
For more information about how query expressions are translated, see my Edulinq post on that topic.

How to convert Linq.ParallelQuery to Linq.IQueryable

var transactions = from t in context.Transactions
group t.Create_Date_Time by t.Participation_Id
into t1
select new { ParticipationId = t1.Key, CreateDateTime = t1.Max() };
var cases = from c in context.Cases
group c.Create_Date_Time by c.Participation_Id
into c1
select new { ParticipationId = c1.Key, CreateDateTime = c1.Max() };
var interactions = (from i in context.Interactions
join pp in context.Party_Participation on i.Party_Id equals pp.Party_Id
group i.Last_Update_Date_Time.HasValue ? i.Last_Update_Date_Time : i.Create_Date_Time by
pp.Participation_Id
into i1
select new {ParticipationId = i1.Key, CreateDateTime = i1.Max()}).AsQueryable();
Considering the above code, following will work
transactions.Union(cases);
However following will not work
transactions.Union(interactions);
Because transactions and cases both are returning Linq.IQueryable but the last one is Linq.ParallelQuery due to it join with an another table.
I need this functionality basically to make Union. interactions.Union(transactions) or transactions.Union(interactions) one with other.
The anonymous type of transactions and cases is the same. The anonymous type of interactions is different!
So the solution is to select in a way that makes the anonymous types the same. So either create your own type or convert the select product's properties to the same type.
Something like this should produce the same anonymous type for all the selects:
select new { ParticipationId = (int)c1.Key, CreateDateTime = (DateTime)c1.Max() }
My answer to this question may be incorrect however I raised up this question primarly for the following problem.
LINQ to Entities Union is throwing an error.
I found a fantastic reply from diceguyd30 and it was solved my problem. Hence I am closing this question in response to my previous question's answer.
interactions.Union(transactions.AsEnumerable());
that should work since the first parameter is IQueryable and the second is IEnumerable
Queryable.Union<TSource> Method (IQueryable<TSource>, IEnumerable<TSource>)

Categories

Resources