简体   繁体   中英

Changing the generated classes from “Code First From Database” EF6

I'm changing from model first to code first with EF6 I'm using the Code first from Database option to generate my classes.

These are going to be used with a WPF application. Unfortunately the items generated do not have ObservableCollections and don't implement INotiftyPropertyChanged.

I'm wondering is there any way to automate this (by changing the behaviour of the classes c# generates when selecting the code first from DB option. Otherwise I'll have to go through and make the changes by hand which will be very tedious as we have over 100 tables.

Sample generated Class (note the properties and class don't implement INotiftyPropretyChanged and the ICollections are initialised as HashSets, when we'd like ObersvableCollections), these requirements are for data binding with WPF/XAML reasons:

{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Data.Entity.Spatial;

    [Table("TerminalSession")]
    public partial class TerminalSession
    {
        public TerminalSession()
        {
            TerminalCheckpoints = new HashSet<TerminalCheckpoint>();
            TerminalFloats = new HashSet<TerminalFloat>();
            TerminalTransactions = new HashSet<TerminalTransaction>();
        }

        public int TerminalSessionID { get; set; }

        public int? TerminalID { get; set; }

        public DateTime? StartDate { get; set; }

        public DateTime? EndDate { get; set; }

        public virtual ICollection<TerminalCheckpoint> TerminalCheckpoints { get; set; }

        public virtual ICollection<TerminalFloat> TerminalFloats { get; set; }

        public virtual ICollection<TerminalTransaction> TerminalTransactions { get; set; }
    }
}

Code we actually want:

{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Data.Entity.Spatial;

    [Table("TerminalSession")]
    public partial class TerminalSession : INotifyPropertyChanged
    {
        private int _terminalSessionId;
        private int? _terminalId;
        private DateTime? _startDate;
        private DateTime? _endDate;

        public TerminalSession()
        {
            TerminalCheckpoints = new ObservableCollection<TerminalCheckpoint>();
            TerminalFloats = new ObservableCollection<TerminalFloat>();
            TerminalTransactions = new ObservableCollection<TerminalTransaction>();
        }

        public int TerminalSessionID
        {
            get { return _terminalSessionId; }
            set
            {
                if (value == _terminalSessionId) return;
                _terminalSessionId = value;
                OnPropertyChanged();
                _terminalSessionId = value;
            }
        }

        public int? TerminalID
        {
            get { return _terminalId; }
            set
            {
                if (value == _terminalId) return;
                _terminalId = value;
                OnPropertyChanged();
                _terminalId = value;
            }
        }

        public DateTime? StartDate
        {
            get { return _startDate; }
            set
            {
                if (value == _startDate) return;
                _startDate = value;
                OnPropertyChanged();
                _startDate = value;
            }
        }

        public DateTime? EndDate
        {
            get { return _endDate; }
            set
            {
                if (value == _endDate) return;
                _endDate = value;
                OnPropertyChanged();
                _endDate = value;
            }
        }

        public virtual ObservableCollection<TerminalCheckpoint> TerminalCheckpoints { get; set; }

        public virtual ObservableCollection<TerminalFloat> TerminalFloats { get; set; }

        public virtual ObservableCollection<TerminalTransaction> TerminalTransactions { get; set; }
        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));

        }
    }
}

Option I'm selecting in visual studio. 在此处输入图片说明

Instructions are available on MSDN at Customizing Code First to an Existing Database .

Basically all you do is add the EntityFramework.CodeTemplates.CSharp NuGet package (or .VisualBasic if that's your preferred language) to your project, and it will add the T4 templates used by the wizard to the CodeTemplates\\EFModelFromDatabase folder in your project.

Then you modify the T4 templates to your liking and re-run the wizard to regenerate the model from your database.

You have the solution here: http://msdn.microsoft.com/en-us/data/jj574514.aspx

It´s in the part

"Updating code generation for data binding"

Regards

I think the answer from Brian Hinchley's answer on this question works for INotiftyPropertyChanged here too (that question was similar only for an earlier version of EF, EF 4.(something).

How to get property change notifications with EF 4.x DbContext generator

If that works, I'll modify my answer with more details + instructions for how to do the observable collection part (just testing it now).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM