linq (to nHibernate): оператор «как в» - PullRequest
2 голосов
/ 30 марта 2011

Привет
Учитывая список строк, я хочу получить все элементы, имена которых содержат одну из указанных строк.
например, с учетом {"foo", "kuku"} я хочу получить сотрудников "Corfoo", "kuku maluku" и "kukufoo".
Я пробовал следующее, но получил исключение с нулевой ссылкой (?)

query.Where(u => values.Any(v=> u.FullName.Contains(v)) );

Следующее выдало исключение «Лямбда-выражение не в области видимости».

query.Where(u => (values.Count(v => u.FullName.Contains(v)) > 0) );

Есть идеи, как это можно сделать?
Я думал о том, как перебрать коллекцию значений и добавить новое условие для каждого элемента.
проблема в том, что функция .Where () - это конъюнкция (И), и мне нужно дизъюнкция (ИЛИ) ...
(Я использую nH 2.1.2 с провайдером Linq; еще не пробовал это на nH3.0 ...)

Ответы [ 3 ]

3 голосов
/ 31 марта 2011

Если вы не ограничены провайдером Linq, но также открыты для API ICriteria, я предлагаю использовать следующее:

List<string> fullnames = new List<string>() { "foo", "kuku" };
// prepare Query
var query = session.CreateCriteria(typeof(Employee));
// dynamically add Like-conditions combined with OR
Disjunction namesCriteria = Restrictions.Disjunction();
foreach (var name in fullnames)
{
    namesCriteria.Add(Restrictions.Like("FullName", name, MatchMode.Anywhere));
}
// add complete Disjunction to prepared query
query.Add(namesCriteria);
IList<Employee> list = query.List<Employee>();

Я думаю, что попробовать это в NHibernate.Linq может быть сложнее, если не невозможно. С NH 3.0 вы можете использовать QueryOver, который избавит от волшебных строк.

1 голос
/ 15 октября 2015

я использовал следующие стили кодирования

QueryOver

IQueryOver<Patient> rowCount = Session.QueryOver<Patient>().ToRowCountQuery();

                    IQueryOver<Patient> result = this.Session.QueryOver<Patient>()
                     .Where(p => (p.FullNameEn.IsLike("%" + criteria.Keyword.Replace(" ", "%") + "%"))
                         || (p.FullNameAr.IsLike("%" + criteria.Keyword.Replace(" ", "%") + "%"))
                         || (p.IdentityNO == criteria.Keyword)
                         || (p.MobileNO == criteria.Keyword)
                         || (p.PatientID == patientIDKeyword)
                      )
                      .OrderBy(p => p.FullNameEn).Asc
                      .Take(criteria.PageSize)
                      .Skip((criteria.Page - 1) * criteria.PageSize);


                    totalCount = result.ToRowCountQuery().FutureValue<int>().Value;
                    transaction.Commit();
                    return result.Future<Patient>().ToList();

LINQ

var query = this.LINQ;
query = query.Where(p => p.VendorNameAr.Contains(criteria.Keyword.Replace(" ", "%")) ||
                                             p.VendorNameEN.Contains(criteria.Keyword.Replace(" ", "%")));
return query.ToList();
1 голос
/ 15 мая 2012

Я использовал следующий код, надеюсь, это поможет;

   public IList<AutoCompleteDto> GetCitiesLike(string text)
    {
        AutoCompleteDto autoCompleteDto = null;

        var cityList = UnitOfWork.CurrentSession.QueryOver<City>()
            .Where(x => x.CityName.IsLike(text, MatchMode.Start))
            .SelectList(u => u
                                 .Select(x => x.Id).WithAlias(() => autoCompleteDto.Id)
                                 .Select(x => x.CityName).WithAlias(() => autoCompleteDto.Name)
                                 .Select(x => x.CityName).WithAlias(() => autoCompleteDto.Value))
            .TransformUsing(Transformers.AliasToBean<AutoCompleteDto>())
            .List<AutoCompleteDto>();


        return cityList;
    }
...