Проблемы с запросом NHibernate - PullRequest
1 голос
/ 24 февраля 2010

В настоящее время я участвую в проекте каталога деталей.

Чтобы получить некоторую справочную информацию, у меня есть 3 сущности nHib, приложение и транспортное средство.

Part.cs

public class Part : Entity
{
    public Part()
    {
        Quality = new PartQuality();
        FitmentPosition = new FitmentPosition();
        OEPartNumbers = new List<OEPartNumber>();
        Applications = new List<Application>();
    }

    public virtual string Description { get; set; }

    [NotNull]
    [NotEmpty]
    [Pattern(@"\d{4}[-]\d{3}$", RegexOptions.None, "Must be a valid part number")]
    [DomainSignature]
    public virtual string PartNumber { get; set; }

    public virtual PartQuality Quality { get; set; }

    public virtual FitmentPosition FitmentPosition { get; set; }

    public virtual string Notes { get; set; }

    public virtual string VehicleComments { get; set; }

    public virtual string Image { get; set; }

    public virtual IList<OEPartNumber> OEPartNumbers { get; set; }

    public virtual IList<Application> Applications { get; set; }
}

Application.cs

public class Application : Entity
{
    [DomainSignature]
    public virtual string Name { get; set; }

    public virtual DateTime DateFrom { get; set; }
    public virtual DateTime DateTo { get; set; }

    // Fuel
    public virtual bool Diesel { get; set; }
    public virtual bool Petrol { get; set; }

    // Transmission
    public virtual bool Manual { get; set; }
    public virtual bool Automatic { get; set; }
    public virtual bool SemiAutomatic { get; set; }

    // Air Con
    public virtual bool WithAC { get; set; }
    public virtual bool WithOutAC { get; set; }

    // Body
    public virtual bool Hatchback { get; set; }
    public virtual bool Saloon { get; set; }
    public virtual bool Convertable { get; set; }
    public virtual bool Estate { get; set; }
    public virtual bool Coupe { get; set; }
    public virtual bool Van { get; set; }

    // Number of Doors
    public virtual bool Doors2 { get; set; }
    public virtual bool Doors3 { get; set; }
    public virtual bool Doors4 { get; set; }
    public virtual bool Doors5 { get; set; }

    [DomainSignature]
    public virtual Part Part { get; set; }

    public virtual IList<Vehicle> Vehicles { get; set; }
}

Vehicle.cs

public class Vehicle : Entity
{
    public virtual string Make { get; set; }

    public virtual string Model { get; set; }

    public virtual string Type { get; set; }

    public virtual string Engine { get; set; }

    public virtual DateTime ProductionStart { get; set; }

    public virtual DateTime ProductionEnd { get; set; }

    public virtual IList<Application> Applications { get; set; }

}

Видно, что деталь может иметь много применений, а приложение может иметь много транспортных средств.

Я пытаюсь свернуть список всех транспортных средств, используя Марку, Модель, Тип и Двигатель, но также выделить, если какое-либо транспортное средство связано с данным Приложением. Я собирался использовать DTO со свойствами make, model, type, engine и islinked (bool).

Я могу нормально отфильтровать отфильтрованные автомобили, но у меня возникла проблема с определением, связано ли транспортное средство с приложением или нет. Было бы хорошо, если бы я мог сделать следующее

IsLinked = ((Vehicle.Applications.Count(x => x.Name == _name) > 0)

Но это не компилируется. Любые идеи ??

Привет

Rich

Ответы [ 3 ]

1 голос
/ 24 февраля 2010

Первоначально я писал запрос с использованием ICritreia (например, Lachlan),

public override IQueryable<ApplicationVehicleSummary> GetQuery(ISession session)
{
        ICriteria criteria = session.CreateCriteria<Vehicle>();

        // SELECT
        criteria
            .SetProjection(
            Projections.Property("Make"),
            Projections.Property("Model"),
            Projections.Property("Type"),
            Projections.Property("Engine")
            );
        // WHERE
        criteria
            .Add(
            Restrictions.Eq("Make", _criteria.Make) &&
            Restrictions.Eq("Model", _criteria.Model) &&
            Restrictions.Eq("Type", _criteria.Type) &&
            Restrictions.Eq("Engine", _criteria.Engine)
            );

        //criteria.Add(Something("IsLinked",Subqueries.Gt(0,subCriteria)));

        criteria.SetResultTransformer(Transformers.AliasToBean<ApplicationVehicleSummary>());

        return criteria.List<ApplicationVehicleSummary>().AsQueryable();
}

Но после прочтения сообщения Джема решил использовать запрос Linq.

public override IQueryable<ApplicationVehicleSummary> GetQuery(ISession session)
    {
        var results = session.Linq<Vehicle>()
            .Select(v => new ApplicationVehicleSummary
                             {
                                 Make = v.Make,
                                 Model = v.Model,
                                 Type = v.Type,
                                 Engine = v.Engine,
                                 IsLinked = v.Applications.Any(a => a.Name == _name)
                             })
            .Where(v =>
                   v.Make == _criteria.Make &&
                   v.Model == _criteria.Model &&
                   v.Type == _criteria.Type &&
                   v.Engine == _criteria.Engine
            );
        return results;
    }

Что работает, спасибо за вашу помощь.

0 голосов
/ 24 февраля 2010

Использование критериев запросов.

Если вы хотите найти эти автомобили для определенного применения:

result = session.CreateCriteria<Vehicle>()
    .CreateAlias( "Applications", "a" )
    .Add( Expression.Eq( "Make ", make ) )
    .Add( Expression.Eq( "a.Name", applicationname ) )
    .List<Vehicle>();

Или вместо фильтрации по имени приложения требуется флаг DTO на его основе:

vehicles = session.CreateCriteria<Vehicle>()
    .Add( Expression.Eq( "Make ", make ) )
    .List<Vehicle>();

dto = vehicles
        .Select(v => new DTO
        {
             IsLinked = v.Applications.Any(a => a.Name == applicationname )
        })
        .ToList();
0 голосов
/ 24 февраля 2010

Я не понял, какой у вас код DTO. но возможно это поможет разобраться.

public class DTO
{
    public bool IsLinked { get; set; }
}

public IList<DTO> Get(string _name)
{
    return Session.Linq<Vehicle>()
            .Select(v => new DTO
                             {
                                 IsLinked = v.Applications.Any(a => a.Name == _name)
                             })
            .ToList();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...