This is a migrated thread and some comments may be shown as answers.

External Resources?

10 Answers 89 Views
ScheduleView
This is a migrated thread and some comments may be shown as answers.
Brandon
Top achievements
Rank 1
Brandon asked on 13 Jul 2015, 07:28 PM

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!

10 Answers, 1 is accepted

Sort by
0
Nasko
Telerik team
answered on 14 Jul 2015, 12:29 PM
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
0
Brandon
Top achievements
Rank 1
answered on 14 Jul 2015, 01:38 PM

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

0
Nasko
Telerik team
answered on 15 Jul 2015, 10:36 AM
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
0
Brandon
Top achievements
Rank 1
answered on 15 Jul 2015, 12:33 PM

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

0
Brandon
Top achievements
Rank 1
answered on 16 Jul 2015, 12:17 PM
BTW, We are running 2014.2.729.40 as the version.
0
Nasko
Telerik team
answered on 17 Jul 2015, 11:38 AM
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
0
Brandon
Top achievements
Rank 1
answered on 17 Jul 2015, 05:27 PM

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

0
Nasko
Telerik team
answered on 21 Jul 2015, 02:24 PM
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
0
Brandon
Top achievements
Rank 1
answered on 24 Jul 2015, 02:19 PM

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

 

0
Nasko
Telerik team
answered on 27 Jul 2015, 06:36 AM
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
Tags
ScheduleView
Asked by
Brandon
Top achievements
Rank 1
Answers by
Nasko
Telerik team
Brandon
Top achievements
Rank 1
Share this question
or