Entity Framework - Stop Lazy Loading Related Entities On Demand?




I have Entity Framework set up and it works fine most of the time I need it. I have a structure like so



```
public partial class Topic : Entity
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public DateTime CreateDate { get; set; }
    public virtual Post LastPost { get; set; }
    public virtual Category Category { get; set; }
    public virtual IList<Post> Posts { get; set; }
    public virtual IList<TopicTag> Tags { get; set; }
    public virtual MembershipUser User { get; set; }
    public virtual IList<TopicNotification> TopicNotifications { get; set; }
    public virtual IList<Favourite> Favourites { get; set; }
    public virtual Poll Poll { get; set; }
}

```

As you can see I have a number of related entities which are lists. These are mapped as standard and are lazy loaded so I can call Topic.Posts or Topic.TopicNotifications etc... (Mappings below)



```
HasOptional(t => t.LastPost).WithOptionalDependent().Map(m => m.MapKey("Post_Id"));
HasOptional(t => t.Poll).WithOptionalDependent().Map(m => m.MapKey("Poll_Id"));            
HasRequired(t => t.Category).WithMany(t => t.Topics).Map(m => m.MapKey("Category_Id"));
HasRequired(t => t.User).WithMany(t => t.Topics).Map(m => m.MapKey("MembershipUser_Id"));
HasMany(x => x.Posts).WithRequired(x => x.Topic).Map(x => x.MapKey("Topic_Id")).WillCascadeOnDelete();
HasMany(x => x.TopicNotifications).WithRequired(x => x.Topic).Map(x => x.MapKey("Topic_Id")).WillCascadeOnDelete();
HasMany(t => t.Tags)
    .WithMany(t => t.Topics)
    .Map(m =>
                {
                    m.ToTable("Topic_Tag");
                    m.MapLeftKey("TopicTag_Id");
                    m.MapRightKey("Topic_Id");
                });

```

This is all an well. But on a couple of occasions I have the need to manually populate Topic.Posts and Topic.Favorites.


But if I try and set `Topic.Posts = SomeCollection` it triggers the lazy load and loads all the posts first, and then lets me set my collection so I get two sets of sql executed (The first I don't want)


Is there anyway, to switch off the lazy loading manually on demand for just when I want to set the collection manually?


Hope that makes sense... :/
You would be better to turn off lazy loading by default and instead specify when you want to load the extra data in the first place. EF is set up to allow Eager loading by using the .Include() function on your query, with lazy loading it can get messy if you start turning it on/off for various functions, you're better to just turn it off and manage what/when you want data loaded if you're feeling a need to turn it off.


See <https://msdn.microsoft.com/en-nz/data/jj574232.aspx> for specific examples and a breakdown of the different ways you can eager/lazy load data. The first example shows how you could pull through posts off a blog, which is similar to what you are wanting to acheive.



```
var topics = context.Topics 
                      .Include(t => t.Posts) 
                      .ToList(); 

```
Using [reflection](/questions/tagged/reflection "show questions tagged 'reflection'") and [expression-trees](/questions/tagged/expression-trees "show questions tagged 'expression-trees'") you can provide the parameters and then call `OrderBy` function, Instead of returning `Expression<Func<Task, T>>` and then calling `OrderBy`.


Note that `OrderBy` is an extension method and has implemented in both `System.Linq.Enumarable` and `System.Linq.Queryable` classes. The first one is for [linq-to-objects](/questions/tagged/linq-to-objects "show questions tagged 'linq-to-objects'") and the latter is for [linq-to-entities](/questions/tagged/linq-to-entities "show questions tagged 'linq-to-entities'"). [entity-framework](/questions/tagged/entity-framework "show questions tagged 'entity-framework'") needs the expression tree of the query in order to translate it to SQL commands. So we use the `Queryable` implementation.


It can be done by an extension method(explanations added as comments):



```
public static IOrderedQueryable<TSource> OrderBy<TSource>(
       this IQueryable<TSource> query, string propertyName)
{
    var entityType = typeof(TSource);

    //Create x=>x.PropName
    var propertyInfo = entityType.GetProperty(propertyName);
    ParameterExpression arg = Expression.Parameter(entityType, "x");
    MemberExpression property = Expression.Property(arg, propertyName);
    var selector = Expression.Lambda(property, new ParameterExpression[] { arg });

    //Get System.Linq.Queryable.OrderBy() method.
    var enumarableType = typeof(System.Linq.Queryable);
    var method = enumarableType.GetMethods()
         .Where(m => m.Name == "OrderBy" && m.IsGenericMethodDefinition)
         .Where(m =>
         {
            var parameters = m.GetParameters().ToList();
            //Put more restriction here to ensure selecting the right overload                
            return parameters.Count == 2;//overload that has 2 parameters
         }).Single();
    //The linq's OrderBy<TSource, TKey> has two generic types, which provided here
    MethodInfo genericMethod = method
         .MakeGenericMethod(entityType, propertyInfo.PropertyType);

    /*Call query.OrderBy(selector), with query and selector: x=> x.PropName
      Note that we pass the selector as Expression to the method and we don't compile it.
      By doing so EF can extract "order by" columns and generate SQL for it.*/
    var newQuery = (IOrderedQueryable<TSource>)genericMethod
         .Invoke(genericMethod, new object[] { query, selector });
    return newQuery;
}

```

Now you can call this overload of `OrderBy` like any other overload of it.  

For example:



```
var cheapestItems = _context.Items.OrderBy("Money").Take(10).ToList();

```

Which translates to:



```
SELECT TOP (10)  {coulmn names} FROM  [dbo].[Items] AS [Extent1] 
       ORDER BY [Extent1].[Money] ASC

```

This approach can be used to define all overloads of `OrderBy` and `OrderByDescending` methods to have `string` property selector. > 
> What attributes I have to attach to the CreatedDate and ModifiedDate properties to make them automatically populated by the server based on the above scenario?
> 
> 
> 


**Solution 1)**



```
namespace Joukyuu.Models
{
    public class Passage
    {
        public int PassageId { get; set; }
        public string Contents { get; set; }


        public DateTime CreatedDate { get; set; }
        public DateTime ModifiedDate { get; set; }

       public Passage()
       {          
         this.CreatedDate  = DateTime.UtcNow;
         this.ModifiedDate = DateTime.UtcNow;
       }
    }
}

```

and by edit you have to change/update it by your self!


**Solution 2)**


Custom attribute:



```
[SqlDefaultValue(DefaultValue = "getutcdate()")]
public DateTime CreatedDate { get; set; }

```

[Entity Framework 6 Code first Default value](https://stackoverflow.com/questions/19554050/entity-framework-6-code-first-default-value)


**Solution 3)**


with help of Computed:



```
[Required, DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime CreatedUtc { get; set; 


  "dbo.Products",
            c => new
                {
                    ProductId = c.Int(nullable: false, identity: true),
                    Name = c.String(),
                    CreatedUtc = c.DateTime(nullable: false, defaultValueSql: "GETUTCDATE()"),
                })
            .PrimaryKey(t => t.ProductId);

```

<https://andy.mehalick.com/2014/02/06/ef6-adding-a-created-datetime-column-automatically-with-code-first-migrations/>


**Solution 4)**
You can also do this with command interceptor by modifying manually the query.


**Solution 5)** 
Use Repository pattern to manage the data creation and set it by CreateNew 
This is my favour Solution!


<https://msdn.microsoft.com/en-us/library/ff649690.aspx>


**Solution 6)** 
just set it or get in in the UI or in your VM.







In **Entity Framework Core 1.0** easy:



```
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Passage>()
        .Property(b => b.CreatedDate )
        .HasDefaultValueSql("getdate()");
}

``` this is not a topic list but a summary of this guide. it uses disco toc a great theme component

[image]

[discotoc - automatic table of contents](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143) [theme](/c/theme/61)

this is a theme component that will allow you to generate an interactive table of contents for your topics with one click! … A trigger is not what you want.


What you need is a scheduled job.


Take a look at the official documentation on the subject:


[Scheduling Jobs with Oracle Scheduler](http://docs.oracle.com/cd/B28359_01/server.111/b28310/scheduse.htm#i1033533)


Feel free to ask more questions if you find any trouble when creating your scheduled job. > 
> i want to create ap application which generates popup alerts at the day of event ocurs as well as a day before the event will occur in a specific time interval as well.. events are stored in database and they are all date fields .. so i want to link those fields to create popups .. help me .
> 
> 
> 


In order to help you, you must first provide us with what you have achieved. We do not write code for you, simply correct and enlighten on mistakes. hello,

this is not possible at this time. you will have to close the topic manually via the admin wrench or set a topic timer for auto close. perhaps you can create a [#feature](/c/feature/2) request for this. You could achieve this with a simple `for` loop:



```
var min = 12,
    max = 100,
    select = document.getElementById('selectElementId');

for (var i = min; i<=max; i++){
    var opt = document.createElement('option');
    opt.value = i;
    opt.innerHTML = i;
    select.appendChild(opt);
}

```

[JS Fiddle demo](https://jsfiddle.net/davidThomas/NX3ac/).


[JS Perf](https://jsperf.com/) comparison of both mine and [Sime Vidas' answer](https://jsperf.com/comparison-of-loops), run because I thought his looked a little more understandable/intuitive than mine and I wondered how that would translate into implementation. According to Chromium 14/Ubuntu 11.04 mine is somewhat faster, other browsers/platforms are likely to have differing results though.







**Edited** in response to comment from OP:



> 
> [How] do [I] apply this to more than one element?
> 
> 
> 



```
function populateSelect(target, min, max){
    if (!target){
        return false;
    }
    else {
        var min = min || 0,
            max = max || min + 100;

        select = document.getElementById(target);

        for (var i = min; i<=max; i++){
            var opt = document.createElement('option');
            opt.value = i;
            opt.innerHTML = i;
            select.appendChild(opt);
        }
    }
}
// calling the function with all three values:
populateSelect('selectElementId',12,100);

// calling the function with only the 'id' ('min' and 'max' are set to defaults):
populateSelect('anotherSelect');

// calling the function with the 'id' and the 'min' (the 'max' is set to default):
populateSelect('moreSelects', 50);

```

[JS Fiddle demo](https://jsfiddle.net/davidThomas/NX3ac/1/).


And, finally (after quite a delay...), an approach extending the prototype of the `HTMLSelectElement` in order to chain the `populate()` function, as a method, to the DOM node:



```
HTMLSelectElement.prototype.populate = function (opts) {
    var settings = {};

    settings.min = 0;
    settings.max = settings.min + 100;

    for (var userOpt in opts) {
        if (opts.hasOwnProperty(userOpt)) {
            settings[userOpt] = opts[userOpt];
        }
    }

    for (var i = settings.min; i <= settings.max; i++) {
        this.appendChild(new Option(i, i));
    }
};

document.getElementById('selectElementId').populate({
    'min': 12,
    'max': 40
});

```

[JS Fiddle demo](https://jsfiddle.net/davidThomas/NX3ac/148/).


References:


* [`node.appendChild()`](https://developer.mozilla.org/en/DOM/node.appendChild).
* [`document.getElementById()`](https://developer.mozilla.org/en/DOM/document.getElementById).
* [`element.innerHTML`](https://developer.mozilla.org/en/DOM/element.innerHTML). Hello, [@Trulines87](/c/user/viewprofilepage/user-id/733134).


Welcome to Shopify Community. My name is Olivia and I work here.


Thanks for posting your question, I can definitely help you out with this today. There are a couple of different ways we can tackle this, so let's dive right in to your options.


**A. Use your design time.**


Each store on a paid plan, using a Shopify developed theme, is allotted a full 60 minutes of design time for minor changes. While it's best to check with our [Support Team](https://bit.ly/2XDcBxK) on what changes we can, and can't accommodate, your request is definitely one we could look after. If you have a specific idea of what you would like your footer to look like let me know and I can connect you with our Theme team. Just be as detailed as possible with your request, maybe even including examples, to help us make the right changes. Make sure to check out our [design policy](https://bit.ly/31wVsHb) to read more about support for Shopify themes.


***OR***


**B. Add text to your footer code.**


If you're comfortable with making code changes you can save your design time for something else. It will be helpful to have basic knowledge of HTML and CSS to help you customize the style and layout of added text, but I can point you towards making these changes on your own. Head to **Shopify Admin > Online Store > Themes > Narrative > Actions > Edit Code** and scroll down to */sections* to find the file **footer.liquid**.


Narrow down this piece of code on line 32:


 



```
{% when 'menu' %}

```

 


Now, insert your text after that line. Make sure to add <p> before your text, and </p> at the end of your text to close the code. Here's an example:


 



```
            {% when 'menu' %}
            <p> Add your contact info </p>
              {%- assign link_list = block.settings.link_list -%}
```

 


This is how it would appear on your website:


![08-26-ndww6-2kmgo](/c/image/serverpage/image-id/57763i1C21A51AE550DEAA/image-size/large?v=1.0&px=999 "08-26-ndww6-2kmgo")


That's it! You can take it a step further and make it even easier for your customers to contact you by adding a direct email link. Simple code like this would work: 


 



```
<a href="mailto:yourmail@domain.com">Insert your business email address</a>
```

 


Same thing for a "click-able" phone number to help customers easily phone you:


 



```
<a href="tel:18001112233">1-800-111-2233</a>
```

 


And we're done! Don't forget to replace the email address and phone number in those codes with your own information.


That should work, but let me know if any other questions come up that I can help with.


Warm regards,



**Olivia | Social Care @ Shopify**  
 - Was my reply helpful? Click **Like** to let me know!   
 - Was your question answered? Mark it as an **Accepted Solution** - To learn more visit the [Shopify Help Center](https://help.shopify.com/) or the [Shopify Blog](https://www.shopify.ca/blog) you might be able to use synchronize. if you have more than 2 tables, you will need to use it multiple times. you should be able to set the element to not be visible on page load, and then on the conditional tab of the element, you should be able to construct a condition where parent group’s thing’s creation date < parent group’s thing’s modified date, this element is visible. and when i say “should be able…