#c# #.net #winforms #entity-framework #linq-to-entities
#c# #.net #winforms #entity-framework #linq-to-entities
Вопрос:
Как я могу преобразовать строку в datetime с помощью linq to entities….
Я получил приведенный ниже запрос, где visit_date
типом данных столбца является строка…
var memberl = from v in abc.visits
join m in abc.members on v.member_Id equals m.member_Id
where Convert.ToDateTime(v.visit_Date) >= startdate amp;amp;
Convert.ToDateTime(v.visit_Date) <= enddate
group m by new { m.member_Firstname,
m.member_Lastname, m.member_Id } into g
orderby g.Count()
select new
{
numVisits = g.Count(),
firstname = g.Key.member_Firstname,
lastname = g.Key.member_Lastname
};
К сожалению, я не могу изменить схему…
У меня ошибка:
linq to entites does not recognise Convert.ToDatetime method
Есть ли какое-либо возможное решение для преобразования строки в Datetime?
Обновленный код:
в соответствии с запросом я обновил свой вопрос
var data = (from v in abc.visits
join m in abc.members on v.member_Id equals m.member_Id
select new
{
MemberID = v.member_Id,
VisiteDate = v.visit_Date,
FirstName = m.member_Firstname,
LastName = m.member_Lastname
}).ToList();
var membersdata = from d in data
where Convert.ToDateTime(d.VisiteDate) >= startdate amp;amp; Convert.ToDateTime(d.VisiteDate) <= enddate
group m by new { d.FirstName, d.LastName, d.MemberID } into g
orderby g.Count()
select new
{
numVisits = g.Count(),
firstname = g.Key.FirstName,
lastname = g.Key.LastName
};
Комментарии:
1. Это цена хранения дат в виде строки… Случайно он не соответствует форме yyyyMMdd?
2. Возможно, посмотрите на функции, определенные моделью , для обработки ситуаций, когда вы можете что-то сделать в TSQL (
CAST(text as datetime)
), но не в EF (Convert.ToDateTime(text)
) . msdn.microsoft.com/en-us/library/dd456857.aspx3. Что это за обновленный код сейчас? Невозможно, чтобы вы получили исключение с этим кодом. Второй запрос больше не связан с объектами, он связан с объектами в памяти и там
Convert.ToDateTime
работает. Не могли бы вы, пожалуйста, проверить опубликованный вами код?
Ответ №1:
Я не думаю, что EF поддерживает преобразование строки в DateTime или наоборот.
Как я вижу, у вас есть два варианта, в зависимости от формата даты в поле string:
Если формат довольно прост, может быть достаточно сравнения строк:
// Convert the boundaries to strings first
// TODO: Set the ToString format option to match the database format
string startDateAsString = startdate.ToString("yyyyMMdd");
string endDateAsString = enddate.ToString("yyyyMMdd");
// Query based on string comparison
var memberl = from v in abc.visits
join m in abc.members on v.member_Id equals m.member_Id
where v.visit_Date.CompareTo(startDateAsString) >= 0 amp;amp;
v.visit_Date.CompareTo(endDateAsString) <= 0
group m by new { m.member_Firstname,
m.member_Lastname, m.member_Id } into g
orderby g.Count()
select new
{
numVisits = g.Count(),
firstname = g.Key.member_Firstname,
lastname = g.Key.member_Lastname
};
Если строковое представление даты является более сложным, и простое сравнение строк не может помочь, вы можете рассмотреть возможность создания a view
в visits
таблице, которая выполняет преобразование для вас на уровне базы данных:
CREATE VIEW VisitsWithDate (MemberId, VisitDate)
AS
SELECT MemberId, Convert(datetime, VisitDate, 112) -- For instance
FROM Visits
С последующим импортом этого представления в вашу модель данных. Возможно, вам потребуется немного поколдовать, чтобы заставить отношения работать.
Надеюсь, это поможет.
Комментарии:
1. @errorcode105: я бы тщательно проверил сравнения дат, потому что сравнение их как строк не гарантирует точности.
2. Согласен. Оговорка с первым решением, безусловно, заключается в формате даты
Ответ №2:
Convert.ToDatetime
поддерживается Linq2SQL. Единственным поддерживаемым методом Linq to entities являются следующие: http://msdn.microsoft.com/en-us/library/bb738681.aspx
о вашей проблеме… попробуйте преобразовать startdate
и enddate
в строку и сравнить строковое значение в выражении linq.
Ответ №3:
Попробуйте преобразовать результаты в List<>
first и отфильтровать результаты из списка:
var data = (from v in abc.visits
join m in abc.members on v.member_Id equals m.member_Id
select new
{
MemberID = v.member_id,
VisiteDate = v.visit_date,
FirstName = m.member_FirstName,
LastName = m.member_LastName
}).ToList();
var memberl = from d in data
where Convert.ToDateTime(d.VisitDate) >= startdate amp;amp; Convert.ToDateTime(d.VisitDate) <= enddate
group d by new { d.FirstName, d.LastName, d.MemberID } into g
orderby g.Count()
select new
{
numVisits = g.Count(),
firstname = g.Key.FirstName,
lastname = g.Key.LastName
};
Комментарии:
1. Преобразовать. ToDateTime(v.visit_Date) >= startdate amp;amp; Convert . ToDateTime(v.visit_Date) <= enddate эта строка больше не работает с использованием сущностей..
2. Извините, только что обновил мой ответ. Необходимо выбрать необходимые столбцы при преобразовании его в список.
3. Я получил сообщение об ошибке в этой строке «сгруппируйте m по new { d.FirstName, d.LastName, d.MemberID } в g», в котором говорится, что «невозможно преобразовать лямбда-выражение в тип system. Коллекции. Общий. IEqualityComparer<Анонимный тип # 2> потому что это не тип делегата» не могли бы вы, пожалуйста, помочь в этом…
4. Это не кажется лучшей идеей, вы будете запрашивать в памяти. И таким образом запрос не становится более читаемым 🙂
5. Это решение, но вы действительно должны подчеркнуть в ответе, что вся нефильтрованная коллекция сначала загружается в память до применения фильтра. Новички могут легко заметить разницу. Представьте, что в этой таблице миллион записей. Тогда следующий вопрос, который мы должны ожидать: «Почему мой запрос, который возвращает только два объекта, такой медленный и потребляет так много памяти?» 🙂
Ответ №4:
Поскольку DateTime и DateTimeOffset являются структурами, они по сути не обнуляются. Когда вам нужна возможность обнуления, есть два способа обойти это:
- Использовать нулевой тип (т.Е. DateTime? или DateTimeOffset?).
- Используйте статическое поле DateTime.MinValue или DateTimeOffset.MinValue (значения по умолчанию для этих типов)