External Resources?

11 posts, 0 answers
  1. Brandon
    Brandon avatar
    15 posts
    Member since:
    Nov 2009

    Posted 13 Jul 2015 Link to this post

    I've started modifying the Database SDK example to support resources that are not in MSSQL so that we can continue to use our external resources that are in different database formats until we can migrate our entire application.

    I've gotten it to load and save the data appropriately to the new AppointmentExternalResources link table, however when I edit an appointment and click save it thinks there are duplicate resources in the this.Resources of the SqlAppointment and then gives an error when saving the ScheduleViewRepository.Context.

    I've made the following changes:

    • SqlResourceTypes - Added ExternalResource (bit)
    • New table SqlAppointmentExternalResources
      • SqlAppointments_SqlAppointmentId (int)
      • SqlResourceTypes_SqlResourceTypeId (int)
      • ResourceName (nvarchar(100)) - Used for the key value of the external database

    Code wise:

        public partial class SqlAppointmentExternalResource
        {
            #region Constants and Variables
            short bStat = 0;
            SqlExternalResource externalResource;
            #endregion
     
            #region Properties
            public SqlExternalResource ExternalResource
            {
                get
                {
                    if (externalResource == null && !string.IsNullOrEmpty(this.ResourceName))
                    {
                        externalResource = new SqlExternalResource();
                        externalResource.ResourceTypeId = this.SqlResourceTypes_SqlResourceTypeId;
                        switch (this.SqlResourceTypes_SqlResourceTypeId)
                        {
                            case 2:
    //load from external database
                                    externalResource.ResourceName = "XXX";
                                    externalResource.DisplayName = "DISPLAY_NAME";
                                break;
                            case 4:
    //load from external database
                                    externalResource.ResourceName = "ADMIN";
                                    externalResource.DisplayName = "ADMINISTRATION";
                                break;
                        }
                    }
                    return externalResource;
                }
                set
                {
                    externalResource = value;
                    this.OnPropertyChanged("ExternalResource");
                }
            }
            #endregion
        }

    • SqlAppointment was changed as follows:
      public IList Resources
      {
          get
          {
              if (this.resources == null)
              {
                  this.resources = new List<object>();
                  foreach (var item in this.SqlAppointmentExternalResources.ToList())
                      this.resources.Add(item.ExternalResource);
                  foreach (var item in this.SqlAppointmentResources.Select(ar => ar.SqlResource).ToList())
                      this.resources.Add((IResource)item);
              }
              return this.resources;
          }
      }
      void IEditableObject.EndEdit()
      {
          #region Standard Telerik Appointment Resources
          var temp = this.SqlAppointmentResources.ToList();
          var resources = this.Resources.OfType<SqlResource>().ToList();
       
          foreach (var item in temp)
              ScheduleViewRepository.Context.SqlAppointmentResources.DeleteObject(item);
       
          foreach (var sqlResource in resources)
              ScheduleViewRepository.Context.AddToSqlAppointmentResources(new SqlAppointmentResource { SqlAppointment = this, SqlResources_SqlResourceId = sqlResource.SqlResourceId });
          #endregion
       
          #region External Appointment Resources
          var temp1 = this.SqlAppointmentExternalResources.ToList();
          var externalResources = this.Resources.OfType<SqlExternalResource>().ToList();
       
          foreach (var item in temp1)
          {
              ScheduleViewRepository.Context.SqlAppointmentExternalResources.DeleteObject(item);
          }
       
          foreach (var sqlResource in externalResources)
          {
              ScheduleViewRepository.Context.AddToSqlAppointmentExternalResources(new SqlAppointmentExternalResource { SqlAppointment = this, SqlResourceTypes_SqlResourceTypeId = sqlResource.ResourceTypeId, ResourceName = sqlResource.ResourceName });
          }
          #endregion
       
          var removedExceptionAppointments = this.exceptionAppointments.Except(this.SqlExceptionOccurrences.Select(o => o.Appointment).OfType<SqlExceptionAppointment>());
          foreach (var exceptionAppointment in removedExceptionAppointments)
          {
              var excResources = exceptionAppointment.SqlExceptionResources.ToList();
              foreach (var item in excResources)
                  ScheduleViewRepository.Context.SqlExceptionResources.DeleteObject(item);
          }
          ScheduleViewRepository.Context.SaveChanges();
      }
    • So in the EndEdit function it has 4 resources in this.Resource and 2 are duplicates of the original 2. I'm not sure where these duplicates are coming from.  Any ideas or help would be greatly appreciated!
  2. Nasko
    Admin
    Nasko avatar
    588 posts

    Posted 14 Jul 2015 Link to this post

    Hi Brandon,

    Using the provided code - snippet we tried to reproduce the observed by you behavior of RadScheduleView, but due to the many custom modifications made on the example we were not able to reproduce it on our side. Could you please provide us a sample that reproduces it and send it to us? Thus we could be able to continue our investigation and provide you with a prompt solution or some detailed technical instructions how to resolve it.

    We are looking forward to hearing from you.

    Regards,
    Nasko
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. UI for WPF is Visual Studio 2017 Ready
  4. Brandon
    Brandon avatar
    15 posts
    Member since:
    Nov 2009

    Posted 14 Jul 2015 in reply to Nasko Link to this post

    Nasko,

    Thank you for your assistance.  I have attached a modified WPF_CS database project.  My additions in code are commented with '//BRANDON - ' to help you see what I've changed. 

    NOTE: The attached .jpg is actually a .ZIP.

    Thanks, Brandon

  5. Nasko
    Admin
    Nasko avatar
    588 posts

    Posted 15 Jul 2015 Link to this post

    Hi Brandon,

    Thank you for the attached sample project. 

    I tested it and it seems everything works as expected - no duplicate Resources are observed. Please check the attached video that demonstrates my approach and let me know if I missed something. Also, could you please provide me some steps to reproduce the issue and some information of the exact version of Telerik controls you are currently using - I tested the project with the latest official released version of the controls?
     
    We are looking forward to hearing from you.

    Regards,
    Nasko
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  6. Brandon
    Brandon avatar
    15 posts
    Member since:
    Nov 2009

    Posted 15 Jul 2015 in reply to Nasko Link to this post

    Nasko,

    The issue occurs when you actually edit the appointment.  When you first create it, it works fine.  It's any subsequent editing that causes it to crash.

    See attached video.

    NOTE: Again the attached .jpg is actually a .zip.

    Thanks,

    Brandon

  7. Brandon
    Brandon avatar
    15 posts
    Member since:
    Nov 2009

    Posted 16 Jul 2015 in reply to Brandon Link to this post

    BTW, We are running 2014.2.729.40 as the version.
  8. Nasko
    Admin
    Nasko avatar
    588 posts

    Posted 17 Jul 2015 Link to this post

    Hello Brandon,

    Thank you for the attached video.

    We were able to reproduce the observed by you behavior on our side and after further investigation it seems it is caused by your custom implementation of the SqlResourceType class. Every time the Resources get loaded you create a new instance of the "resources" property and thus a new resource is created and added to the collection Resources. So, we suggest you to change the implementation of the class as it follows:
    public partial class SqlResourceType : IResourceType
    {
        private List<SqlExternalResource> resources = new List<SqlExternalResource>();
        public System.Collections.IList Resources
        {
            get
            {
                //BRANDON - Only return the default list if this is not an external resource
                if (!this.ExternalResource)
                    return this.SqlResources.ToList();
     
                //BRANDON - Load my List of External Resource values for the dropdowns.
                    
                switch (this.SqlResourceTypeId)
                {
                    case 4:
                        SqlExternalResource r = new SqlExternalResource();
                        r.ResourceTypeId = this.SqlResourceTypeId;
                        r.ResourceName = "XXX";
                        r.DisplayName = "XXX - DISPLAY_NAME";
                        if(!this.resources.Any(a => a.DisplayName == r.DisplayName))
                        {
                            resources.Add(r);
                        }
                        r = new SqlExternalResource();
                        r.ResourceTypeId = this.SqlResourceTypeId;
                        r.ResourceName = "YYY";
                        r.DisplayName = "YYY - DISPLAY_NAME";
                        if (!this.resources.Any(a => a.DisplayName == r.DisplayName))
                        {
                            resources.Add(r);
                        }
                        break;
                }
                return resources;
            }
        }
    }

    Thus everything should work as expected.

    We hope this will help you.

    Regards,
    Nasko
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  9. Brandon
    Brandon avatar
    15 posts
    Member since:
    Nov 2009

    Posted 17 Jul 2015 in reply to Nasko Link to this post

    Thanks for the suggestion, however the issue remains. 

    I can add an appointment, save, edit that appointment, save.  Then I close and relaunch and edit the same appointment and try and save and it has multiple items in the this.Resources in the SqlAppointment still.

    Thanks, Brandon

  10. Nasko
    Admin
    Nasko avatar
    588 posts

    Posted 21 Jul 2015 Link to this post

    Hi Brandon,

    We were able to reproduce the observed by you behavior. It is caused by the exact same reason as your initial issue. When the application is started everytime a new instance of the "resource" property is created and added to the collection of Resources. As you are loading and creating that List of external resources everytime the application is loaded the only workaround that we could suggest you is inside the EndEdit method to implement some custom logic that removes the unnecessary resource and preserve in the collection only the latest added external resource. The following code - snippet represents some custom implementation of the described above approach:
    void IEditableObject.EndEdit()
    {
        #region Standard Telerik Appointment Resources
        var temp = this.SqlAppointmentResources.ToList();
        var resources = this.Resources.OfType<SqlResource>().ToList();
     
        if(this.Resources.Count > 3)
        {
            var exResources = this.Resources.OfType<SqlExternalResource>().ToList();
     
            if(exResources.Count > 1)
            {
                this.Resources.RemoveAt(0);
            }
        }
    ...
    }

    Due to your custom scenario this is the only approach that currently we could suggest.

    We hope this will help you.

    Regards,
    Nasko
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  11. Brandon
    Brandon avatar
    15 posts
    Member since:
    Nov 2009

    Posted 24 Jul 2015 in reply to Nasko Link to this post

    Thanks.  For those looking to do the same thing, I've modified EndEdit as follows to account for any ResourceTypeId being modified(duplicated).

    #region External Appointment Resources
     
    var temp1 = this.SqlAppointmentExternalResources.ToList();
    var externalResources = this.Resources.OfType<SqlExternalResource>().ToList();
     
    List<int> usedResources = new List<int>();
    for (int i = externalResources.Count-1; i >= 0; i--)
    {
        if (usedResources.Contains(externalResources[i].ResourceTypeId))
            externalResources.RemoveAt(i);
        else
            usedResources.Add(externalResources[i].ResourceTypeId);
    }
     
    foreach (var item in temp1)
        ScheduleViewRepository.Context.SqlAppointmentExternalResources.DeleteObject(item);
     
    foreach (var sqlResource in externalResources)
        ScheduleViewRepository.Context.AddToSqlAppointmentExternalResources(new SqlAppointmentExternalResource { SqlAppointment = this, SqlResourceTypes_SqlResourceTypeId = sqlResource.ResourceTypeId, ResourceName = sqlResource.ResourceName });
    #endregion

     

  12. Nasko
    Admin
    Nasko avatar
    588 posts

    Posted 27 Jul 2015 Link to this post

    Hello Brandon,

    We are glad that you were able to achieve the desired and thank you for sharing your approach with the community.

    If you have any additional questions or concerns regarding Telerik controls, please do not hesitate to contact us.

    Regards,
    Nasko
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top
UI for WPF is Visual Studio 2017 Ready