0

I am new to .net core, here is the official repository from telerik for code first approach on schedule view :

https://github.com/telerik/xaml-sdk/tree/master/ScheduleView/DatabaseEntityFramework

if you take a look at the DbContext file here ....

https://github.com/telerik/xaml-sdk/blob/master/ScheduleView/DatabaseEntityFramework/ScheduleViewEntities.cs

you will see multiple instances that the fluent API is using WithOptional (line 85 & 90). Reading around the web, people say that if the foreign key is nullable, we can delete these lines and everything would be ok. Now here is the problem :

modelBuilder.Entity<TimeMarker>()
                .HasMany(e => e.SqlAppointments)
                .WithOptional(e => e.TimeMarker)
                .HasForeignKey(e => e.TimeMarkerID);

looking at SqlAppointments class we have these :

public int? TimeMarkerID { get; set; }

public virtual TimeMarker TimeMarker { get; set; }

I assume, here the ID is nullable so it should be ok. the other one :

modelBuilder.Entity<TimeMarker>()
                .HasMany(e => e.SqlExceptionAppointments)
                .WithOptional(e => e.TimeMarker)
                .HasForeignKey(e => e.TimeMarkerID);

it is building a relationship between SqlExceptionAppointments and TimeMarker. The Id for TimeMarker is : TimeMarkerId Looking into the SqlExceptionAppointment class we have :

public int? TimeMarkerID { get; set; }

public virtual TimeMarker TimeMarker { get; set; }

So, did I understand everything right? If we tweak these two relation definitions like :

modelBuilder.Entity<TimeMarker>()
                .HasMany(e => e.SqlAppointments)
                .HasForeignKey(e => e.TimeMarkerID);

modelBuilder.Entity<TimeMarker>()
                .HasMany(e => e.SqlExceptionAppointments)
                .HasForeignKey(e => e.TimeMarkerID);

removing the withoptional, using MySql database here, will everything work in entity framework core?

one more bigger headache, on dbcontext line 69 we have :

modelBuilder.Entity<SqlExceptionOccurrence>()
                .HasOptional(e => e.SqlExceptionAppointment)
                .WithRequired(e => e.SqlExceptionOccurrence)
                .WillCascadeOnDelete();

here is the main issue, looking into SqlExceptionOccurrence we have:

public partial class SqlExceptionOccurrence
    {
        [Key]
        public int ExceptionId { get; set; }

        public int MasterSqlAppointmentId { get; set; }

        public DateTime ExceptionDate { get; set; }

        public virtual SqlAppointment SqlAppointment { get; set; }

        public virtual SqlExceptionAppointment SqlExceptionAppointment { get; set; }
    }

and looking into SqlExceptionAppointment we have :

public partial class SqlExceptionAppointment
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public SqlExceptionAppointment()
        {
            SqlExceptionResources = new HashSet<SqlExceptionResource>();
        }

        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int ExceptionId { get; set; }

        [StringLength(100)]
        public string Subject { get; set; }

        [StringLength(500)]
        public string Body { get; set; }

        public DateTime Start { get; set; }

        public DateTime End { get; set; }

        public bool IsAllDayEvent { get; set; }

        [StringLength(100)]
        public string TimeZoneString { get; set; }

        public int Importance { get; set; }

        public int? TimeMarkerID { get; set; }

        public int? CategoryID { get; set; }

        public virtual Category Category { get; set; }

        public virtual SqlExceptionOccurrence SqlExceptionOccurrence { get; set; }

        public virtual TimeMarker TimeMarker { get; set; }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<SqlExceptionResource> SqlExceptionResources { get; set; }
    }

No, here we don't have ANY foreign key for SqlExceptionOccurrence or SqlExceptionAppointment, looks like both classes are using ExceptionId as their KEY ! how to handle this .HasOptional(e => e.SqlExceptionAppointment) in the mentioned relation definition?

Thanks for your help

1 Answers1

0

Ok, until someone clarify everything, here is what I think will work? unfortunately, I can't try and test because there is no interface yet to give it a try !

for the first two sections :

public int? TimeMarkerID { get; set; }

[ForeignKey("TimeMarkerID")]
public virtual TimeMarker TimeMarker { get; set; }

using the annotation marking the foreign key,

modelBuilder.Entity<TimeMarker>()
            .HasMany(e => e.SqlAppointments)
            .WithOptional(e => e.TimeMarker)
            .HasForeignKey(e => e.TimeMarkerID);

should be like this?

modelBuilder.Entity<TimeMarker>()
            .HasMany(e => e.SqlAppointments);

same for the next one on Time Maker I asked before?

But, when it comes to the last one,

modelBuilder.Entity<SqlExceptionOccurrence>()
            .HasOptional(e => e.SqlExceptionAppointment)
            .WithRequired(e => e.SqlExceptionOccurrence)
            .WillCascadeOnDelete();

Will this work ?

modelBuilder.Entity<SqlExceptionAppointment>()
            .HasOne(e => e.SqlExceptionOccurrence)
            .WithOne(e => e.SqlExceptionAppointment)
            .IsRequired(false);