Entity Definition and reference fields

Apr 29, 2014 at 1:23 PM
Hi,

I am trying to create a simple database (using latest source of ORM, for netcf 3.5 windows ce, sqlite latest version).

I want to design 3 tables with foreign keys :
  • Task (taskId, name)
    • Item (itemId, task, name)
    • SubItem (subItemId, item, name)
I am lost with the ReferenceFieldAttribute. Is this the correcte declaration ?
    [Entity(KeyScheme.None)]
    public class Task
    {
        [Field(IsPrimaryKey = true, AllowsNulls = false)]
        public string TaskId { get; set; }

        [Field]
        public string Name { get; set; }

        [Reference(typeof(Item), "Task", "TaskId", Autofill = true, ReferenceType = ReferenceType.OneToMany)]
        public Item[] Items { get; set; }
    }

    [Entity(KeyScheme.None)]
    public class Item
    {
        [Field(IsPrimaryKey = true, AllowsNulls = false)]
        public string ItemId { get; set; }

        [Field(AllowsNulls = false)]
        public string Task { get; set; }

        [Field]
        public string Name { get; set; }

        [Reference(typeof(Task), "TaskId", "Task", Autofill = true, ReferenceType = ReferenceType.OneToMany)]
        public Task ParentTask { get; set; }

        [Reference(typeof(SubItem), "Item", "ItemId", Autofill = true, ReferenceType = ReferenceType.ManyToOne)]
        public SubItem[] SubItems { get; set; }
    }

    [Entity(KeyScheme.None)]
    public class SubItem
    {
        [Field(IsPrimaryKey = true, AllowsNulls = false)]
        public string SubItemId { get; set; }

        [Field(AllowsNulls = false)]
        public string Item { get; set; }

        [Field]
        public string Name { get; set; }
        
        [Reference(typeof(Task), "ItemId", "Item", Autofill = true, ReferenceType = ReferenceType.OneToMany)]
        public Item ParentItem { get; set; }
    }
Thanks :)
Apr 29, 2014 at 2:00 PM
I have written some test code :

It seams that the current ORM version has one limitation : we can't specify navigation properties (ReferenceAttribute) to navigate back and forth (parent => chilren and child => parent).

I have created a helper attribute :
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public sealed class FKChildrenAttribute : ReferenceAttribute
    {
        public FKChildrenAttribute(string myField, Type childEntity, string childField)
            : base(childEntity, /*foreignReferenceField*/ childField, /*localReferenceField*/ myField)
        {
            this.ReferenceType = ReferenceType.OneToMany;
        }
    }
So I can write :
    [Entity(KeyScheme.None)]
    public class Task
    {
        [Field(IsPrimaryKey = true, AllowsNulls = false)]
        public string TaskId { get; set; }

        [Field]
        public string Name { get; set; }

        //[Reference(typeof(Item), "Task", "TaskId", Autofill = true, ReferenceType = ReferenceType.OneToMany)]
        //[Reference(typeof(Item), "Task", "TaskId", Autofill = true, ReferenceType = ReferenceType.OneToMany)]
        [FKChildrenAttribute("TaskId", typeof(Item), "Task", Autofill = true)]
        public Item[] Items { get; set; }
    }

    [Entity(KeyScheme.None)]
    public class Item
    {
        [Field(IsPrimaryKey = true, AllowsNulls = false)]
        public string ItemId { get; set; }

        [Field(AllowsNulls = false)]
        public string Task { get; set; }

        [Field]
        public string Name { get; set; }
    }
I have changed attribute reflection (DataStore.AddType : var reference = prop.GetCustomAttributes(true).Where(a => a.GetType().Equals(typeof(ReferenceAttribute)) || a.GetType().IsSubclassOf(typeof(ReferenceAttribute))).FirstOrDefault() as ReferenceAttribute;)

I have also changed in SQLStoreBase some things in DoInsertReferences : it seams that there is a confusion between LocalReferenceField and ForeignReferenceField.
I have also added a workaround to test the "isNew" for KeyScheme.None.