MuriloKunze
MuriloKunze

Reputation: 15593

Exclude property when selecting data

I have a class with a virtual property (public virtual List<Ingredients>), but in some cases I don't want to get that data. How can I do this? I know about .Include and .Select, but if I do that, I need to change lots of code cause in my repository I return a Queryable and Service layer too.

Upvotes: 2

Views: 4179

Answers (3)

peter70
peter70

Reputation: 1123

You cann simply build a class SubClass (that inherit from SomeCompany) and includes the Property you need, that schould not be included into your proxy class (SomeCompany).

For example a class

SomeCompany

public class SomeCompany
{
    public virtual string SomeProperty { get; set; }
    public virtual Company MyCompany { get; set; }
}

public class SomeCompanyEx : SomeCompany
{
    public string CompanyName { get; set; }

    public override Company MyCompany
    {
        get
        {
            return this.myCompany;
        }

        set
        {
            this.SetProperty(ref this.myCompany, value);

            if (value != null)
            {
                this.CompanyName = value.Name;
            }
            else
            {
                this.CompanyName = null;
            }
        }
    }
}

The class SomeCompanyEx you can use, for example, in list object and so on... So you have now the property CompanyName you can use in your program, but no in your proxy classes.

Upvotes: 0

Gert Arnold
Gert Arnold

Reputation: 109347

An indirect answer: I would not expose IQueryable in a service layer. For (at least) three reasons:

  • You must keep the context alive for when a navigation property is accessed.
  • The layers that use your service layer can profoundly influence the SQL emitted to the database. You want to be in control of that that in your service or repository.
  • Unit testing your service layer is very hard.

So if you expose IEnumerables of objects that you need in your application you can offer objects that have exactly those navigation properties loaded that are needed in a specific scenario. E.g. a maintenance function for product entities (name etc.) would get bare products only (and no code would ever access ingredients). A function that composes products from ingredients would get its ingredients as well. Service/repository methods should have parameters to specify what you need.

If you want 100% guarantee that lazy navigation properties are not going to be accessed you need to expose projected objects (or DTO's) to your application.

Upvotes: 5

Judo
Judo

Reputation: 5247

By default related properties are not returned and you need to use an Include() to specify returning a related property.
This may not always be clear as if you are using lazy loading you do not need to explicitly request the related property, EF will determine if the related property is required when it is requested and add it to the database request.

To test this force the LINQ query to execute when you declare it by appending .First() and the look at the object returned which should have no related properties.

Edit It is not possible to load only certain properties from a related property. If you load the related property all its properties will automatically be loaded.

Upvotes: 0

Related Questions