Отражение в Linq

#c# #linq #reflection

#c# #linq #отражение

Вопрос:

Эта строка кода:

 db.Set<T>().Max(d => d.GetType().GetProperty("DateTimePropertyName").GetValue(d))
  

вызывает это исключение:

 LINQ to Entities does not recognize the method 'System.Object GetValue(System.Object)' method
  

Как мне заставить это работать?

Комментарии:

1. Я думаю, это не сработает, потому что вы запрашиваете базу данных, которая не будет поддерживать GetType ()…

2. Важно ли, чтобы вычисления выполнялись на стороне сервера? По сути, вы просите сервер вычислить что-то, что LinqToEntities не может передать серверу.

Ответ №1:

Вы пытаетесь запустить код c #, который, как предполагается, каким-то образом должен быть переведен в SQL, и не можете.

Это хорошее руководство для начала.

У вас есть два варианта:

1. Извлеките данные из базы данных и просмотрите их с помощью LINQ to Objects — вероятно, самый простой, но не лучший способ сделать что-либо, поскольку некоторые запросы могут возвращать большие коллекции.

2. Попытайтесь найти лучший способ сделать то, что вы делаете. Почему вы хотите, чтобы этот код отражения выполнялся? Какова цель? Является ли DateTimePropertyName непубличным? Если да, то почему? В противном случае должно сработать что-то вроде этого:

 db.Set<T>().Max(d => d.DateTimePropertyName);
  

Комментарии:

1. Это универсальный класс, и мне нужно сделать это на стороне сервера.

2. Вам следует удалить «== Something» и, возможно, дать какой-нибудь код в 1. В остальном, хороший ответ. 1

3. @MarkusJohnsson — Ты прав.. Я сделал == Кое-что по ошибке 🙂

Ответ №2:

По умолчанию предполагается, что вы передаете Expression<Func<T,TResult>> , но что вам нужно, так это передать Func<T,TResult> :

 Func<T, object> f = p => p.GetType().GetProperty("DateTimePropertyName").GetValue(p); 
_context.Set<T>().Max(f);
  

Это происходит из IEnumerable, поэтому это повлияет на производительность, если ваша таблица большая