0

I'm currently using Linq to Sql (dbml) for one of my projects. (c# win forms)

I've created partial and metadata classes, and also implemented Equals() and == based on these Guidelines

the problem I'm having is when I try to use these equals operations within a linq query.

Entities.MyClass.Where(p => p.Equals(myClassObject));

I've also attempted the following

Entities.MyClass.Where(p => Object.Equals(p, myClassObject));
Entities.MyClass.Where(p => p == myClassObject);

What's the best way to implement this?

Instead of attempting to override Equals I'm currently doing the following (but I'm checking 8 values, so it just seems cumbersome) :

Entities.MyClass.Where(p => p.value1 == myClassObject.value1 && p.value2 == myClassObject.value2 ......)
John Grabanski
  • 363
  • 7
  • 20
  • What exactly is the problem? Are you getting an error, or do you just not like having to check 8 values? – Mage Xy Nov 06 '15 at 18:06
  • I always use the rule of thumb when comparing `Objects` I use the `.Equals` method when comparing values i use the `==` comparison – MethodMan Nov 06 '15 at 18:07
  • 1
    I'm assuming the issue is that your Linq provider doesn't know how to convert the `Equals` or the `==` operator you've setup for your entity. Typically you'd do comparisons with your primary key, unless you're specifically testing for rows that match some set of columns. – juharr Nov 06 '15 at 18:08
  • Is it a Linq-to-Objects query (i.e. the object set being queried is in memory) or a Linq-to-SQL query (the query is being run against the database)? – Radu Porumb Nov 06 '15 at 18:08
  • Are you trying to do a join the hard way? – Robert McKee Nov 06 '15 at 18:33
  • The problem is that I know that I know there's a row in my DB that matches the Equal operator I've set up. and from the comments and answers, Linq just doesn't know about it. The purpose for the check is to call out that someone is trying to enter a value into the db that 'already exists', Id's wont work b/c the myClassObject was created in memory. – John Grabanski Nov 06 '15 at 18:39

2 Answers2

3

LINQ to SQL (or any other LINQ provider that translates your LINQ expressions into provider queries for that matter), doesn't have knowledge of how you've overriden Equals.

Consequently, when you use your Equals method in a LINQ query, the provider doesn't know that it should compare using your 8 properties.

You could pre-process your LINQ query, before it's handled by the LINQ provider, by traversing the expression tree and expanding calls to your Equals method into the corresponding 8 property comparison. This way, the LINQ provider gets an expression for your implementation. If the equals implementation changes, you only have to change it in two places (the Equals override and the corresponding substitution expression).

Michael Petito
  • 12,891
  • 4
  • 40
  • 54
  • How would I go about pre-processing the LINQ, I only have a limited knowledge with LINQ, mainly using it so I woudn't have to write SQL queries and so I can easily data-bind without creating my own classes. Is there a resource you can point me to? Google "pre-processing Linq query" isn't very helpful thus far. – John Grabanski Nov 06 '15 at 18:57
  • Also I'm currently only checking if it's equal once, is it simpler to just check the 8 properties and forget about the Overrides and pre-processing? I wanted to build the overrides for possible future changes, but it seems I'm just stepping on my own feet. – John Grabanski Nov 06 '15 at 19:09
  • 1
    If this is only in one place, it probably makes sense to just check the 8 properties. Otherwise, you'll end up having to traverse and modify expression trees, which can be challenging to get right. There are some solutions out there to provide a framework for implementing such *expandable* queries if you're still interested, such as http://tomasp.net/blog/linq-expand.aspx . – Michael Petito Nov 06 '15 at 19:18
0

You must create an Expression<Func<M,V>> object to pass to the where clause. You could put the answer to this question in a method and create it that way.

Community
  • 1
  • 1
Aaron Gates
  • 469
  • 4
  • 15