2016-12-04 2 views
1

Если я загрузить объект через Entity Framework, и сохраняются его позже использовать - например, в фильтре равенства - Entity Framework выдает следующее сообщение об ошибке:Как упорядочить сравнение равенства объектов памяти в условии Entity Framework?

Unable to create a constant value of type 'MyType'. Only primitive types or enumeration types are supported in this context.

Это может затем быть легко решена с помощью идентифицирующий значение/значение на MyType, например .Where(x => x.Name == MyTypeMemoryInstance.Name).

Однако мне было интересно, есть ли альтернатива, позволяющая сравнивать равенство без необходимости предоставления примитивного типа, поэтому я могу сделать .Where(x => x == MyTypeMemoryInstance) вместо этого и все еще делать это в SQL, а не в памяти.

Концептуально это можно решить, если я могу предоставить перевод LINQ-to-SQL с использованием определенного примитивного типа для использования для данного типа, аналогичного переопределению регулярного сравнения равенства в C#, но я не знаю, это действительно возможно. Спасибо.

ответ

1

Лучшее, что я могу думать, потому что в том, где положение у вас есть Func бы:

public class MyType 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 

    public Func<MyType, bool> GetQuery() 
    { 
     // or whatever equals you would like 
     return x => x.Name == this.Name && x.Id == this.Id; 
    } 
} 

Затем используйте его, как, например:

var first = ctx.MyTypes.First(); 
var listContainingLoadedThings = ctx.MyTypes.Where(first.GetQuery()).ToList(); 
0

Проблема: запросы Linq to Entities переводятся на SQL. Поставщик Linq не может преобразовать два экземпляра объекта, чтобы сравнить их в sql. Вот почему это генерирует это исключение, потому что ему нужно работать с примитивными типами, как в SQL.

В одном решении может использоваться метод расширения AsEnumerable, чтобы перейти от Linq к объектам в Linq к объектам. Если вы сделаете что-то вроде:

var query=context.YourDbSet.AsEnumerable().Where(x => x== MyTypeMemoryInstance).... 

Но будьте осторожны с этим решением. Вы будете загружать все строки из этой таблицы в память. Другим частичным решением может быть, если у вас есть более чем одно условие, то можно применить несколько фильтров первой, а затем применить сравнение, например, если вам действительно нужно сделать так:

var query=context.YourDbSet.Where(...).AsEnumerable().Where(x => x== MyTypeMemoryInstance).... 
+0

Спасибо - да, я знаю, о сравнении в памяти, но на самом деле хотел, чтобы автоматизировать этот процесс в переводе SQL вместо , По сути, я надеялся, что провайдер LINQ to SQL сможет узнать (через IComparer, атрибут и т. Д.) То, что я хочу использовать для сравнения равенства, и использовать это при разрешении выражения сравнения равенства. – Alex

+0

Я боюсь, что сравнение невозможно на уровне сервера :(Но почему вы не можете сравнивать свойства множественности с обоих объектов вместо сравнения экземпляров? Насколько я знаю, он еще не существует, что позволяет вам определить, как лечить/перевести экземпляр объекта для сравнения в sql – octavioccl

Смежные вопросы