Git Product home page Git Product logo

Comments (7)

cburgdorf avatar cburgdorf commented on June 26, 2024

Assuming Title is you custom property. Then this is probably because your custom property is aggregating data from a related entity. If that's the case you need to use an Include. However, you don't need the Include in case you already use the property in your query, because EF then knows about it. That's why it's working in your first example.

from linq.translations.

AlexKeySmith avatar AlexKeySmith commented on June 26, 2024

Hi cburgdorf,

Thanks for the quick response.

I've just tweaked it to include the related entity (is this what you mean?), but it didn't work unfortunately:

var thisDoesNotWork = (from lr in LearningResources
                        select lr
                        ).Include(lr => lr.LearningResource_MultitenantCustomisation).WithTranslations();

Unless perhaps should I be doing this on the expression itself somehow?

from linq.translations.

AlexKeySmith avatar AlexKeySmith commented on June 26, 2024

Here is an example of the expression if it helps:

 private static readonly CompiledExpression<LearningResource, string> titleExpression = DefaultTranslationOf<LearningResource>.Property(lr => lr.Title)
            .Is(lr =>
                lr.LearningResource_MultitenantCustomisation.FirstOrDefault(tenantCustomisation => tenantCustomisation.BusinessUnitID == MyBUID && tenantCustomisation.LearningResourceID == lr.LearningResourceID).Title
                ?? lr.TitleInternal

                );

Interestingly my property is doing an evaluation like in the examples (I couldn't get this to work properly), instead it's just a plain:

public string Title
        {
            get;
            set;
        }

from linq.translations.

damieng avatar damieng commented on June 26, 2024

It's really designed to be used in the where criteria and in all cases the expression should be capable of being evaluated on the client or the server so in the second case the property should still work fine. If you're trying to do something odd on that property with side-effects or things that can't be evaluated client-side it's probably not going to work.

from linq.translations.

AlexKeySmith avatar AlexKeySmith commented on June 26, 2024

Thanks Damien,

What I'm doing is swapping out a column with a column for a left joined table (well a db view really). So it's a little odd what I'm trying to do, but I don't think it has side-effects.

In the example where I'm just grabbing the title column, if I set a break point in ExpressiveExtensions.cs it hits

VisitCompiledExpression

Via:

if (map.TryGetValue(node.Member, out cp)) {
                    return VisitCompiledExpression(cp, node.Expression);
 }

But does not in the example when selecting the whole entity. Is there a way do you think that I'll be able to trigger the expression without the where clause?

from linq.translations.

damieng avatar damieng commented on June 26, 2024

Basically when the WithTranslations visitor executes it replaces all property accesses with the expression. Your second example never references the property so there is nothing for it to replace.

The problem you're going to have is that Entity Framework or LINQ to SQL are not going to be happy returning an Entity object that has had one of the normally stored properties changed behind the scenes - both systems like to be in charge of materializing their objects.

About the best I can think of would be something like:

var thisDoesNotWork = (from lr in LearningResources
select new { Title = lr.Title, Full = lr).WithTranslations()'
foreach(var item in thisDoesNotWork) item.Full.Title = item.Title;

The problem there however is going to be that now the objects are marked as dirty and will rewrite the fake title as the real title if you make any changes.

Probably the safest thing to do would be to add a property that is not stored/mapped in the database called CalculatedTitle that has the expression and have the app refer to that.

from linq.translations.

AlexKeySmith avatar AlexKeySmith commented on June 26, 2024

Thanks for the info Damien.

Good news, we managed to get the column displaying, it was my dodgy CompiledExpression! It was throwing an exception in the background which asp.net was hiding:

 private static readonly CompiledExpression<LearningResource, string> titleExpression = DefaultTranslationOf<LearningResource>.Property(lr => lr.Title)
            .Is(lr =>
                lr.LearningResource_MultitenantCustomisation.FirstOrDefault(tenantCustomisation => tenantCustomisation.BusinessUnitID == MyBUID && tenantCustomisation.LearningResourceID == lr.LearningResourceID).Title
                ?? lr.TitleInternal

                );

Should of read:

private static readonly CompiledExpression<LearningResource, string> titleExpression = DefaultTranslationOf<LearningResource>.Property(lr => lr.Title)
            .Is(lr =>
                lr.LearningResource_MultitenantCustomisation.FirstOrDefault(tenantCustomisation => tenantCustomisation.BusinessUnitID == MyBUID && tenantCustomisation.LearningResourceID == lr.LearningResourceID) != null ? 
                lr.LearningResource_MultitenantCustomisation.FirstOrDefault(tenantCustomisation => tenantCustomisation.BusinessUnitID == MyBUID && tenantCustomisation.LearningResourceID == lr.LearningResourceID).Title : lr.TitleInternal

                );

When I used (below), it would work when getting the single column, but not the whole entity.

public string Title
        {
            get; set;
        }

If I used the following it revealed the exception. Guessing the expression visitor kicks in when explicitly loading columns, but you need to call the expression directly if just loading the whole entity - but I couldn't figure this out due to my dodgy expression.

public string Title
        {
            get
            {
                return titleExpression.Evaluate(this);                
            }
            set
            {
                this.TitleInternal = value;
            }
        }

Thanks for the help, I wouldn't of noticed it without your assistance. Plus using the include has helped optimise it a bit. I like the idea of the wrapped { Title = lr.Title, Full = lr } I'll keep that in my toolbelt for another day, thanks again.

from linq.translations.

Related Issues (8)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.