entity-frameworkvisual-studio-2010c#-4.0nhibernatedapper-simplecrud

How to setup my code as DB First in an ORM


I have looked at using EF, nHibernate and Dapper/Dapper.SimpleCRUD. In none of them can I figure out how to represent my use case in regards to my database (SQL Server 2012) model. I am building an ASP.NET website with a grid in C# 4.0/.NET 4.0 (due to technical limitations) that will have CRUD capabilities, with the initial state of the grid being set by dropdowns.

My two tables are set up as such:

Address_Book 
 |_[EntryID]
 |_[Last_Name]
 |_[First_Name]
 |_[Title]
 |_[Office_Num]
 |_[Cell_Num]
 |_[Home_Num]
 |_[Email_Address]
 |_[Special_Info]
 |_[hr24_Emails]
 |_[hr48_Emails]
 |_[RM_Emails]
 |_[Prestige_Emails]
 |_[GEB_Emails]
 |_[LAW_Emails]

Distribution
 |_[Brand]
 |_[Location_Mnemonic]
 |_[Location_Code_Numeric]
 |_[EntryID]
 |_[Division_Mnemonic]
 |_[Region_Mnemonic]
 |_[Zone_Mnemonic]
 |_[District_Mnemonic]
 |_[Key]

With a many-to-one relationship between Distribution and Address_Book where Address_book.EntryID = Distribution.EntryID.

Any help with how to set this up would be appreciated. I am having issues managing the CRUD operations manually, so I thought an ORM would help, but I cannot figure it out. Any help is appreciated.

Thanks in advance!


Solution

  • The whole .net CRUD thing is a big realm with a lot of flavors and ways of doing the work. And while I don't know exactly where you are at with this, the following my help out. In my experience EF can handle relationships quite well, though the whole EF learning process is a bit steep and I've shied away from it. I typically use Dapper with extensions and do stuff pseudo-manually. I haven't used the SimpleCrud extension. Since you inherited the DB, hopefully it's set up well and there's a FK constraint on Distribution, Column EntryID.

    In Dapper, you could set up your classes like:

    using Dapper.Contrib.Extensions;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.SqlClient;
    
    namespace Jacrys
    {
        [Table("dbo.address_book")]
        public partial class AddressBook
        {
            [Dapper.Contrib.Extensions.Key]
            public int EntryID { get; set; }
            public string Last_Name { get; set; }
            public string First_Name { get; set; }
            public string Title { get; set; }
            public string Office_Num { get; set; }
            public string Cell_Num { get; set; }
            public string Home_Num { get; set; }
            public string Email_Address { get; set; }
            public bool Special_Info { get; set; }
            public bool hr24_Emails { get; set; }
            public bool hr48_Emails { get; set; }
            public bool RM_Emails { get; set; }
            public bool Prestige_Emails { get; set; }
            public bool GEB_Emails { get; set; }
            public bool LAW_Emails { get; set; }
    
            //use this only if you need all of the distributions to be
            //part of your main AddressBook class
            public IEnumerable<Distribution> Distributions { get; set; } 
    
            public static AddressBook GetById(short id)
            {
                using (IDbConnection cn = new SqlConnection("getConnString"))
                {
                    cn.Open();
                    return cn.Get<AddressBook>(id);
                }
            }
    
            public static IEnumerable<AddressBook> GetAll()
            {
                using (IDbConnection cn = new SqlConnection("getConnString"))
                {
                    cn.Open();
                    return cn.GetAll<AddressBook>();
                }
            }
    
            public int Insert()
            {
                using (IDbConnection cn = new SqlConnection("getConnString"))
                {
                    cn.Open();
                    return (int)cn.Insert(this);
                }
            }
            public bool Update()
            {
                using (IDbConnection cn = new SqlConnection("getConnString"))
                {
                    cn.Open();
                    return cn.Update(this);
                }
            }
            public bool Delete()
            {
                using (IDbConnection cn = new SqlConnection("getConnString"))
                {
                    cn.Open();
                    return cn.Delete(this);
                }
            }
        }
    
        [Table("dbo.distribution")]
        public partial class Distribution
        {
            [Dapper.Contrib.Extensions.Key]
            public int Key { get; set; }
            public int EntryID { get; set; }
            public string Brand { get; set; }
            public string Location_Mnemonic { get; set; }
            public int Location_Code_Numeric { get; set; }
            public string Division_Mnemonic { get; set; }
            public string Region_Mnemonic { get; set; }
            public string Zone_Mnemonic { get; set; }
            public string District_Mnemonic { get; set; }
    
            //similar CRUD methods to AddressBook follow here
        }
    }
    

    Then with a GridView like:

    <asp:GridView ID="gvAddresses" runat="server" AutoGenerateColumns="true" DataKeyNames="EntryID">
     </asp:GridView>
    

    You can load it up in the code behind with (and adding lambda expression for pre-sorting):

     gvAddresses.DataSource = Jacrys.AddressBook.GetAll().OrderBy(c=>c.Last_Name);
    

    Any dropdowns you need can be loaded in similar ways.

    Everything depends on your needs. If you have a gridview of Distribution, then you can add in a dropdown for Address when in edit mode (in the row data bound event). When you go to update and save, you'll have to find the control in the row and parse it's selected value before saving the record. There really isn't a nifty one single way to get this done. Though, if you have all of your business classes set up with CRUD methods you can wire it all together more simply.