Click here to Skip to main content
15,905,913 members

Welcome to the Lounge

   

For discussing anything related to a software developer's life but is not for programming questions. Got a programming question?

The Lounge is rated Safe For Work. If you're about to post something inappropriate for a shared office environment, then don't post it. No ads, no abuse, and no programming questions. Trolling, (political, climate, religious or whatever) will result in your account being removed.

 
GeneralRe: Code First Pin
raddevus11-Oct-18 9:10
mvaraddevus11-Oct-18 9:10 
GeneralRe: Code First Pin
R191112-Oct-18 3:14
R191112-Oct-18 3:14 
GeneralRe: Code First Pin
Gerry Schmitz12-Oct-18 4:00
mveGerry Schmitz12-Oct-18 4:00 
GeneralRe: Code First Pin
raddevus12-Oct-18 4:04
mvaraddevus12-Oct-18 4:04 
GeneralRe: Code First Pin
Gerry Schmitz12-Oct-18 4:35
mveGerry Schmitz12-Oct-18 4:35 
GeneralRe: Code First Pin
Foothill11-Oct-18 3:18
professionalFoothill11-Oct-18 3:18 
GeneralRe: Code First Pin
MarkTJohnson11-Oct-18 3:25
professionalMarkTJohnson11-Oct-18 3:25 
GeneralCode Last Pin
Marc Clifton11-Oct-18 3:50
mvaMarc Clifton11-Oct-18 3:50 
R1911 wrote:
Is this something we should definitely aspire to achieve
No.

or it's okay to continue with DB first approach?
Yes.

Code often enough wants to see the data in a different way than is best for DB performance and normalization. I prefer to implement the DB first and generate the model (classes) from the DB (as partial classes so I can, if necessary, extend them with helpful properties, and either create views in the DB or views in the code from the model.

Furthermore, by specifying my DB models myself and using FluentMigrator and a custom tool that I wrote, I can also specify attributes on the fields that drive the UI behavior, like:

{Name: 'IsManager', Type: 'bool', IsDisplayField: true, DisplayName: 'Is Manager?' },

Add comments to the metadata, like:

{Name: 'IsCommunityStaff', Type: 'bool', Comment: 'For community cash drawer support.'},

Specify interfaces that the model should implement, like:

{Name: 'Fingerprint', Implements: 'IFingerprint',

custom formatting (I'm using DevExpress for the UI controls) like:
{Name: 'TaxRate', Type: 'decimal', ActualType: 'Number4', IsDisplayField: true, DisplayName: 'Tax Rate as %', Format: '###0.0000'},

drive lookups implemented as dropdowns like:

{Name: 'DisputeTypeId', Type: 'int', DisplayName: 'Type', FK: 'DisputeType.Id', IsDisplayField: true, LookupModel: 'DisputeType', LookupField: 'Name' },

and specify initial load of data when creating the DB from scratch, like:
{ Name: 'DisputeType', IsLookup: true, Fields:
    [
        {Name: 'Id', IsPK: true, Type: 'int', IsIdentity: true },
        {Name: 'Code', Type: 'int' },
        {Name: 'Name', Type: 'string', IsDisplayField: true },
        {Name: 'Description', Type: 'string', Nullable: true, IsDisplayField: true  },    
    ],
    InitialLoad: 
    [
        {Code: 0, Name: 'Shopper', Description: 'Did not receive products/services, dissatisfied, not refunded, etc.'},
        {Code: 1, Name: 'Process Error', Description: 'Charged twice, charged incorrect amount.'},
        {Code: 2, Name: 'Fraud', Description: 'Stolen card.'},
        {Code: 3, Name: 'Friendly Fraud', Description: 'Customer claims valid purchase was fraudulent, etc.'},
        {Code: 4, Name: 'Other'},
    ]
},

and implement custom code generation, for example when a table has a a field called "Archived":

{Name: 'Archived', Type: 'bool'},

which generates the code for me to archive the record if it's referenced by other tables when the record is deleted:
public void OnDeleted(RowDeletedEventArgs args)
{
    if (((IReferenced)args.Entity).IsReferenced())
    {
        ArchiveController.Archive<TaxCode>(args.Entity);
        args.Handled = true;
    }
}

(Though I'm thinking of changing that to use an IsArchivable attribute on the table rather than rely on a specific field name.)

The end result is that the model metadata specifies:
  • the DB
  • additional characteristics of the model class, like interfaces
  • initial data load
  • UI behavior
  • generates code for custom behaviors like archiving
  • additional documentation as comments useful for the developer
and as mentioned, it generates all the code needed to work with FluentMigrator.

I haven't looked at EF in ages, but I doubt it can do all of this stuff, which reduces my model development and maintenance time by easily 90%. I've done demos with my client where he'll say, oh, I'd like this field formatted as blah, or I'd like an additional field for this option, and I'll edit the JSON metadata, generate the migration code, run it, and the app reflects the changes, without touching a line of code.

So, you might say, I adhere to a "Code Last" principle. Laugh | :laugh:

[edit]Oh, an from the JSON metadata I generate a "report" on the schema -- it's relationships, tables that are just lookups, tables that support archiving, dependencies on archivable tables, etc., which is useful to review to make sure my model is designed correctly.[/edit]

[edit2]And did I mention that it's WinForm / Web agnostic, particularly when using a web UI like jQWidgets - JavaScript UI Widgets framework which requires only a little bit of client-side Javascript to manipulate it for the desired effects based on the JSON schema.
Latest Article - A Concise Overview of Threads

Learning to code with python is like learning to swim with those little arm floaties. It gives you undeserved confidence and will eventually drown you. - DangerBunny

Artificial intelligence is the only remedy for natural stupidity. - CDP1802


modified 11-Oct-18 9:57am.

GeneralRe: Code Last Pin
Mycroft Holmes11-Oct-18 11:57
professionalMycroft Holmes11-Oct-18 11:57 
GeneralRe: Code Last Pin
Marc Clifton11-Oct-18 13:43
mvaMarc Clifton11-Oct-18 13:43 
GeneralRe: Code Last Pin
R191111-Oct-18 19:57
R191111-Oct-18 19:57 
GeneralRe: Code Last Pin
Marc Clifton12-Oct-18 4:05
mvaMarc Clifton12-Oct-18 4:05 
GeneralRe: Code Last Pin
R191113-Oct-18 21:19
R191113-Oct-18 21:19 
GeneralRe: Code First Pin
MadMyche11-Oct-18 4:12
professionalMadMyche11-Oct-18 4:12 
GeneralRe: Code First Pin
theokr11-Oct-18 21:31
theokr11-Oct-18 21:31 
GeneralRe: Code First Pin
KBZX500011-Oct-18 21:47
KBZX500011-Oct-18 21:47 
GeneralRe: Code First Pin
Gerry Schmitz12-Oct-18 3:42
mveGerry Schmitz12-Oct-18 3:42 
GeneralRe: Code First Pin
maze312-Oct-18 4:52
professionalmaze312-Oct-18 4:52 
QuestionOi Lord Griffington! Pin
megaadam10-Oct-18 23:36
professionalmegaadam10-Oct-18 23:36 
AnswerRe: Oi Lord Griffington! Pin
OriginalGriff11-Oct-18 0:24
mveOriginalGriff11-Oct-18 0:24 
GeneralCan I ask a question... Pin
glennPattonWork310-Oct-18 22:24
professionalglennPattonWork310-Oct-18 22:24 
GeneralRe: Can I ask a question... Pin
Slacker00710-Oct-18 22:46
professionalSlacker00710-Oct-18 22:46 
GeneralRe: Can I ask a question... Pin
glennPattonWork310-Oct-18 23:01
professionalglennPattonWork310-Oct-18 23:01 
GeneralCCC Thursday - We have a winner! Pin
megaadam10-Oct-18 22:00
professionalmegaadam10-Oct-18 22:00 
GeneralRe: CCC Thursday Pin
pkfox10-Oct-18 23:56
professionalpkfox10-Oct-18 23:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.