【问题标题】:Changing the generated classes from "Code First From Database" EF6从“Code First From Database”EF6 更改生成的类
【发布时间】:2014-12-15 15:58:07
【问题描述】:

我正在使用 EF6 从模型优先更改为代码优先 我使用 Code first from Database 选项来生成我的类。

这些将与 WPF 应用程序一起使用。 不幸的是,生成的项目没有 ObservableCollections,也没有实现 INotiftyPropertyChanged。

我想知道是否有任何方法可以自动执行此操作(通过更改 C# 在首先从 DB 选项中选择代码时生成的类的行为。否则我将不得不手动进行更改,这将是非常乏味,因为我们有 100 多张桌子。

示例生成的类(注意属性和类不实现 INotiftyPropretyChanged 并且 ICollections 被初始化为 HashSet,当我们想要 ObersvableCollections 时),这些要求适用于与 WPF/XAML 的数据绑定原因:

{
    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; }
    }
}

我们真正想要的代码:

{
    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));

        }
    }
}

我在 Visual Studio 中选择的选项。

【问题讨论】:

    标签: c# wpf entity-framework


    【解决方案1】:

    说明可在 MSDN 上Customizing Code First to an Existing Database 获得。

    基本上,您所做的只是将EntityFramework.CodeTemplates.CSharp NuGet 包(或 .VisualBasic,如果这是您的首选语言)添加到您的项目中,它会将向导使用的 T4 模板添加到您项目中的 CodeTemplates\EFModelFromDatabase 文件夹中。

    然后根据自己的喜好修改 T4 模板并重新运行向导以从数据库中重新生成模型。

    【讨论】:

    • 很好的答案。然而,遗憾的是没有给出关于如何更新 .t4 模板的指导。搜索了高和低,无法弄清楚这一点。想出了如何编辑 EntityType.t4 以将 Hashset 更改为 Observable Collection,但不知道如何为 ICollection 执行此操作。有人知道吗?
    【解决方案2】:

    您可以在这里找到解决方案: http://msdn.microsoft.com/en-us/data/jj574514.aspx

    它在零件中

    “更新数据绑定的代码生成”

    问候

    【讨论】:

    • 我认为只有使用 DatabaseFirst 才能做到这一点(我首先使用代码并首先从现有数据库生成代码)。
    【解决方案3】:

    我认为 Brian Hinchley 对此问题的回答也适用于 INotiftyPropertyChanged (该问题仅适用于早期版本的 EF,EF 4。(某些东西)。

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

    如果可行,我将修改我的答案,提供更多详细信息以及有关如何执行可观察收集部分的说明(现在只是测试它)。

    【讨论】:

    • 您可以使用一些信息——比如创建一个具有通用功能的基类以供模型继承——但您将不得不从头开始进行自己的模板更改。与我在以前版本中看到的代码相比,它们在 EF6 中看起来非常不同。
    • @afrazier,我几乎可以使用它,但是我无法让它使用 _camelCase 生成我的字段,必须为名为 CamelCase 的属性执行 _CamelCase,除了其他一切正常.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多