danyolgiax
danyolgiax

Reputation: 13086

Orchard querying joined entities

I've a content part adds a one-to-one relation:

public class AddResellerPart : ContentPart<AddResellerPartRecord>
{

    private readonly LazyField<ResellerPart> _reseller = new LazyField<ResellerPart>();

    public LazyField<ResellerPart> ResellerField { get { return _reseller; } }

    public ResellerPart Reseller
    {
        get { return _reseller.Value; }
        set { _reseller.Value = value; }
    }
    ...

I've implemented the handler:

    OnInitializing<AddResellerPart>(PropertySetHandlers);
    OnLoaded<AddResellerPart>(LazyLoadHandlers);
    ...

Now if in a controller I do something like this:

var customer = _orchardServices.ContentManager
                    .Query<AddResellerPart, AddResellerPartRecord>()
                    .List().First();

var name = customer.Reseller.Description;

It works like a charm! But if I try this:

var customer = _orchardServices.ContentManager
                    .Query<AddResellerPart, AddResellerPartRecord>()
                    .Where(x => x.Reseller.Description.Contains(filterDescription))
                    .List().First();

I get the error:

"could not resolve property: Reseller.Descriptionof:
myproject.Core.Models.AddResellerPartRecord"

I think this il related to the fact that join between entities is managed by the handler and NHibernate knows nothing about AddResellerPart and Reseller relation.

I also tryied to override mapping in this way:

public class PersistenceConfiguration : ISessionConfigurationEvents {

  public void Created(FluentConfiguration cfg, AutoPersistenceModel defaultModel) {
      defaultModel.Override<AddResellerPart>(mapping => mapping.References(x => x.Reseller, "Reseller_Id"));
  }

Nothing seems to change!

How can I accomplish this?

Upvotes: 2

Views: 737

Answers (1)

danyolgiax
danyolgiax

Reputation: 13086

After hours in which I felt like a sorcerer who throws bat wings into the cauldron, I managed to make it all work like this:

var query =_orchardServices.ContentManager.HqlQuery()
         .Join(alias=>alias.ContentPartRecord<AddResellerPartRecord>());

var defaultHqlQuery = query as DefaultHqlQuery;
var fiJoins = typeof(DefaultHqlQuery).GetField("_joins", BindingFlags.Instance | BindingFlags.NonPublic);
var joins = fiJoins.GetValue(defaultHqlQuery) as List<Tuple<IAlias, Join>>;
joins.Add(new Tuple<IAlias, Join>(new Alias("myproject.Core.Models"), new Join("ResellerPartRecord", "ResellerAlias", ",")));
Action<IHqlExpressionFactory> joinOn = predicate => predicate.EqProperty("Id", "addResellerPartRecord.Reseller");
query = query.Where(alias => alias.Named("ResellerAlias"), joinOn);

query = query.Where(alias => alias.Named("ResellerAlias"), predicate => predicate.Like("Description", filterDescription, HqlMatchMode.Anywhere));
var users = query.List();

now I guess... is this the right and "simplest" way?

Upvotes: 3

Related Questions