0

I am using entity framework code first and mapping our unidata files to tables to get data. I am wanting to join the tables or use navigation properties. The 2 tables share a common field called WorkInProgressOperationId. I have tried using join and navigation properties but it does not seem to work when mapping to unidata files.Is this possible?

        public class WorkInProgressMapping : EntityTypeConfiguration<WorkInProgress>
{

    public WorkInProgressMapping()
    {          
        this.ToTable("WIPMASTER");
        this.HasKey(e => e.WorkInProgressId).Ignore(e => e.EntityId);           
        this.Property(e => e.WorkInProgressId).HasColumnName("@ID");
        this.Property(e => e.SequenceNumber).HasColumnName("OPER_SEQ_NBR");
        this.Property(e => e.WorkOrderNumber).HasColumnName("WORK_ORDER");
        this.Property(e => e.StartQuantity).HasColumnName("SCHED_COMP_QTY");
        this.Property(e => e.JobNumber).HasColumnName("JOB_NBR");
        this.Property(e => e.JobDetailId).HasColumnName("JOBDET_ID");
        this.Property(e => e.ComputerGeneratedNumber).HasColumnName("CPN");
        this.Property(e => e.ItemNumber).HasColumnName("ITEM_NBR");
        this.Property(e => e.ParentWorkOrder).HasColumnName("PARENT_WO");
        this.Property(e => e.ParentDueDate).HasColumnName("SCHED_COMP_DATE");
        this.Property(e => e.WorkOrderIssueDate).HasColumnName("RELEASE_DATE");
        this.Property(e => e.WorkInProgressOperationId).HasColumnName("WIPOPERACT_ID");
    }
}

        public class WorkInProgressOperationMapping : EntityTypeConfiguration<WorkInProgressOperation>
{

    public WorkInProgressOperationMapping()
    {
       this.ToTable("WIPOPER");
       this.HasKey(e => e.WorkInProgressOperationId).Ignore(e => e.EntityId);
       this.Property(e => e.WorkInProgressOperationId).HasColumnName("@ID");
       this.Property(e => e.OperationNumber).HasColumnName("OPERATION_NBR");
       this.Property(e => e.OperationSequence).HasColumnName("OPER_SEQ");
       this.Property(e => e.WorkOrder).HasColumnName("WORK_ORDER");
       this.Property(e => e.NextSequence).HasColumnName("NEXT_SEQ");
       this.Property(e => e.Status).HasColumnName("OPER_STATUS");
       this.Property(e => e.QuantityComplete).HasColumnName("QTY_COMPLETE");
       this.Property(e => e.SalesOrderDeliveryDate).HasColumnName("DUE_SO");
       this.Property(e => e.WorkOrderDeliveryDate).HasColumnName("WO_DUE");
       this.Property(e => e.StartingQuantity).HasColumnName("EXP_START_QTY");

    }
}
James Morris
  • 353
  • 5
  • 20
  • In our example (provided with installation) we have Unidata “Student.cs” Class for Code First. Did you try that? U2 Toolkit for .NET v1.3.0 does not support Entity Framework 6.0. Are you developing using EF 6.0? Is this class “EntityTypeConfiguration” only for EF 6.0 ? Could you please provide me your example? I will try to simulate with our ‘’demo’ Unidata Account. I need to debug the code with your example. Please send me your code to u2askus@rocketsoftware.com. Rajan Kumar – Rajan Kumar Jan 18 '14 at 18:17
  • Please send me the error and log file in this email : u2askus@rocketsoftware.com – Rajan Kumar Jan 18 '14 at 18:19

3 Answers3

0

I was able to put navigation property between two UniData Tables. I have used Composite Key/Foreign Key. Is this your requirement?

See Example below.

I have used the following:

U2 Database

  • UniData 7.3
  • Demo account with STUDENT_NF_SUB and STUDENT_CGA_MV_SUB tables
  • Demo account is normalized with VSG

Microsoft

  • Visual Studio 2012 Update 4
  • .NET Framework 4.5
  • Entity Framework 5.0 (Install-Package Entity Framework -Version 5.0.0)
  • Code First Model
  • WinFrom App

UniData Table in Server Explorer

See below Unidata tables in Visual Studio 2012’s Server Explore.

SE.png

Model and DbContext Code

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test_EF5
{
    public class Student
    {
        public string StudentID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public virtual ICollection<StudentSemester> Semesters { get; set; }
    }

    public class StudentSemester
    {
        public string StudentID { get; set; }
        public string Semester { get; set; }
        public int CompositeKey { get; set; }
        public virtual Student Student { get; set; }
    }
    public class StudentMapping : EntityTypeConfiguration<Student>
    {
        public StudentMapping()
        {
            this.ToTable("STUDENT_NF_SUB");
            this.Property(e => e.StudentID).HasColumnName("ID");
            this.Property(e => e.FirstName).HasColumnName("FNAME");
            this.Property(e => e.LastName).HasColumnName("LNAME");
            this.HasKey(e => e.StudentID);
        }

    }

    public class StudentSemesterMapping : EntityTypeConfiguration<StudentSemester>
    {
        public StudentSemesterMapping()
        {
            this.ToTable("STUDENT_CGA_MV_SUB");
            this.Property(e => e.StudentID).HasColumnName("ID");
            this.Property(e => e.Semester).HasColumnName("SEMESTER");
            this.Property(e => e.CompositeKey).HasColumnName("CGA_MV_KEY");
            this.HasKey(e => new { e.StudentID, e.CompositeKey });

        }

    }
    public class StudentContext : DbContext
    {
        public StudentContext()
        {

        }
        public DbSet<Student> Students { get; set; }
        public DbSet<StudentSemester> StudentSemesters { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Configurations.Add(new StudentMapping());
            modelBuilder.Configurations.Add(new StudentSemesterMapping());

        }
    }
}

WinForm App to call the Code First with Navigation Property

private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                Database.SetInitializer<StudentContext>(null);
                StudentContext ctx = new StudentContext();
                var r = ctx.Students.ToList();
                foreach (var item in r)
                {
                    this.textBox1.AppendText("ID="+item.StudentID+" FNAME=" + item.FirstName +" LNAME="+ item.LastName +Environment.NewLine);

                    foreach (var item2 in item.Semesters)
                    {
                        this.textBox1.AppendText("\t ID="+item2.StudentID + " Semester="+item2.Semester +" CompositeKey="+ item2.CompositeKey +Environment.NewLine);
                    }
                }
            }
            catch (Exception e4)
            {
                string lErr = e4.Message;
                this.textBox1.AppendText(lErr);
            }

        }

Run the App

RunApp.png

Rajan Kumar
  • 718
  • 1
  • 4
  • 9
  • Thanks Rajan for the sample code. I will give this a try today. – James Morris Jan 20 '14 at 12:49
  • Rajan.My Uidata file "WIPMASTER" has a field called "WIPOPERACT_ID" which corresponds to Id of the "WIPOPER" file, and the "WIPOPER" file has a "WORK_ORDER" field that corresponds back to the "WIPMASTER" file.Can I have a one "WIPMASTER" to many "WIPOPERS"relationship with these 2 tables? If so how do I map the Haskeys? – James Morris Jan 20 '14 at 16:17
  • Yes, I think this is possible. HasRequired(),WithMany() and HasForeignKey() allow you to create one (WIPMASTER) to many relation (WIPOPERS). Could you please add the following lines in Class WorkInProgressOperationMapping and try again? HasKey(e => new { e. WorkInProgressOperationId }); HasRequired(p => p. WorkInProgress) .WithMany(b => b. WorkInProgressOperation) .HasForeignKey(p => new { p. WORK_ORDER }); – Rajan Kumar Jan 21 '14 at 05:53
  • Do not forget to add this code in Class WorkInProgress and Class WorkInProgressOperation. Class WorkInProgress { public virtual ICollection< WorkInProgressOperation > WorkInProgressOperations { get; set; } } Class WorkInProgressOperation { public virtual WorkInProgress WorkInProgress { get; set; } } – Rajan Kumar Jan 21 '14 at 05:54
  • The latest example worked for me Rajan. Out of curiosity how many trips will that make to the db using navigation properties when querying 2 tables. I appreciate your help. – James Morris Jan 21 '14 at 13:55
  • Hi James, Thank you. I am glad it worked for you. You can use Include() function to perform Eager Loading. It will make one server trip and it will get data “WorkInProgressOperation” and “WIPMASTER” tables. See above source code for Include() function. – Rajan Kumar Jan 22 '14 at 18:28
0

Another Example : One to Many Relation (U2 Tables/Files)

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test_EF5
{


    public class Customer
    {
        public string CustomerID { get; set; }
        public string FirstName { get; set; }

        public virtual ICollection<Rental> Rentals { get; set; }
    }

    public class Rental
    {
        public string RentalID { get; set; }
        public string CustomerID { get; set; }
        public decimal Balance { get; set; }
        public virtual Customer Customer { get; set; }
    }

    public class CustomerMapping : EntityTypeConfiguration<Customer>
    {
        public CustomerMapping()
        {
            this.ToTable("MEMBERS");
            this.Property(e => e.CustomerID).HasColumnName("MEMBERS_PK");
            this.Property(e => e.FirstName).HasColumnName("FIRST_NAME");
            this.HasKey(e => e.CustomerID);
        }

    }

    public class RentalMapping : EntityTypeConfiguration<Rental>
    {
        public RentalMapping()
        {
            this.ToTable("RENTAL_DETAILS");
            this.Property(e => e.RentalID).HasColumnName("RENTAL_DETAIL_PK");
            this.Property(e => e.Balance).HasColumnName("BALANCE.DUE");
            this.Property(e => e.CustomerID).HasColumnName("CUSTOMER.CODE");


            this.HasKey(e => new { e.RentalID });
            HasRequired(p => p.Customer)
                .WithMany(b => b.Rentals)
                .HasForeignKey(p => new { p.CustomerID });

        }

    }

    public class CustomerContext : DbContext
    {
        public CustomerContext()
        {

        }
        public DbSet<Customer> Customers { get; set; }
        public DbSet<Rental> Rentals { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Configurations.Add(new CustomerMapping());
            modelBuilder.Configurations.Add(new RentalMapping());

        }
    }
}
Rajan Kumar
  • 718
  • 1
  • 4
  • 9
0

Eager Loading with Include() function

private void button3_Click(object sender, EventArgs e)
        {


            try
            {
                Database.SetInitializer<CustomerContext>(null);
                CustomerContext ctx = new CustomerContext();
                var r = ctx.Customers.Include("Rentals").ToList();
                foreach (var item in r)
                {
                    this.textBox1.AppendText("ID=" + item.CustomerID + " FNAME=" + item.FirstName + Environment.NewLine);
                    int k = 0;
                    foreach (var item2 in item.Rentals)
                    {
                        this.textBox1.AppendText("\t ID=" + item2.RentalID + " CustomerID=" + item2.CustomerID + " Balance=" + item2.Balance + Environment.NewLine);

                    }
                }

                int y = 0;
            }
            catch (Exception e4)
            {
                string lErr = e4.Message;
                this.textBox1.AppendText(lErr);
            }

        }
Rajan Kumar
  • 718
  • 1
  • 4
  • 9