2009-03-16 4 views
7

В базе данных у меня есть таблица с именем Contact. Первое имя и другие такие строковые поля предназначены для использования типа данных Char (а не для моей базы данных). Мой объект. Сопоставьте карты с типом строки в свойствах. Если бы я хотел, чтобы сделать простой тест с извлечением Контактного объекта по идентификатору, я хотел бы сделать что-то вроде этого:Как обрезать значения, используя Linq to Sql?

Contact contact = db.Contacts.Single(c => c.Id == myId); 
Contact test = new Contact(); 
test.FirstName = "Martin"; 

Assert.AreEqual(test.FirstName, contact.FirstName); 

Значение contact.FirstName является «Martin» из-за типа полукокса. Где я могу перехватить свойство FirstName при его загрузке? OnFirstNameChanging (строковое значение) не вызывается при начальной загрузке (контакте), а на тестовом объекте.

ответ

8

Возможно, вы могли бы поместить его в метод OnLoaded() частично? Примечание: я никогда не использовал это, но я предполагаю, что это будет выглядеть так:

public partial class Contact 
{ 
    partial void OnLoaded() 
    { 
     FirstName = FirstName.Trim(); 
    } 
} 
+0

Это работает. Его довольно легко сделать для каждого поля, потому что я не показываю, что много полей для отображения. Благодарю. – Marsharks

+0

Это будет генерировать событие с измененным свойством, которое может вызвать другие действия, и может привести к ненужным обновлениям базы данных, поскольку вы меняете значение свойства без внесения каких-либо семантических изменений в контент. – tvanfosson

+3

Суть вопроса заключалась в том, чтобы найти место для такой логики (в этом случае OnLoaded()); Сам метод мог бы легко состоять из «_FirstName = _FirstName.Trim();» чтобы избежать неправильной смены события. –

1
Contact contact = db.Contacts.Single(c => c.Id.Trim() == myId); 

И проверьте, что поставщик LINQ переводит это в соответствующий SQL.

+0

Я не думаю, что проблема была в поле Идентификация. – tvanfosson

+1

@tvanfosson - Я думаю, что op предназначался только для примеров, а не буквально. –

6

Если вы не можете изменить схему, вы можете захотеть, чтобы создатель сгенерировал accessor private/protected и создал общедоступный аксессуар для интерфейса этого свойства в частичной реализации класса. Затем вы можете обрезать значение в get accessor.

public partial class Contact 
{ 

    public string RealFirstName 
    { 
     get { return this.FirstName.Trim(); } 
     set { this.FirstName = value; } 
    } 

    ... 
} 
+1

Это хорошее решение, потому что не только поля имеют тип char, но также и имя First_Name. Поэтому я мог бы исправить все поля, не изменяя его в моем объектном дизайнере. – Marsharks

+0

Проблема заключается в том, когда я создаю запрос и пытаюсь использовать что-то наподобие FullName = c.FirstName + '' + c.LastName. Я получал сообщение Could not translate и не мог рассматривать его как локальное выражение Message. – Marsharks

+0

После того, как вы сделали свою фильтрацию, вы можете использовать ToList() для генерации фактического запроса, а затем сделать свой выбор в результирующем списке. Поскольку они являются объектами в этот момент, должно быть выполнено построение FullName. – tvanfosson

0

Вы можете запустить ForEach в вашем списке контактов, прежде чем пытаться искать Мартина.

var contacts = db.Contacts.ForEach(c => c.FirstName = c.FirstName.Trim()); 
Contact contact = contacts.Single(c => c.Id == myId); 
contact.FirstName // = "Martin" 

Но этот способ не очень прост в обслуживании, если это необходимо для нескольких полей.

+0

Что произойдет, если у него будет 100 000 контактов? –

1

Это зависит от того, какой у вас контроль над схемой и кодом.

Если значения устанавливаются вызовом конструктора со всеми параметрами, выполняются обрезки и т. Д., Поскольку они назначаются переменным-членам.

Если они назначены свойствам (возможно, из примера), измените аксессуар SET так, чтобы он обрезал его.

У вас действительно есть потенциальные проблемы, если вы на самом деле ХОТЯТЬ ведущие или конечные пробелы в какой-то момент.

Если вы не можете изменить код базового класса, попробуйте использовать частичные классы или наследовать от класса и переопределить свойства там.

Если вы не можете этого сделать, то моим последним предложением было бы написать фабричный класс, который вы передаете созданному объекту, и он очищает его по правилам, которые вы хотите.

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