【问题标题】:Entity framework database first protected constructor实体框架数据库第一个受保护的构造函数
【发布时间】:2014-11-13 14:23:31
【问题描述】:

首先使用实体​​框架数据库时如何使我的构造函数受到保护?

当我从我的数据库生成实体数据模型时,自动生成的类包含一个公共构造函数,

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated from a template.
//
//     Manual changes to this file may cause unexpected behavior in your application.
//     Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace Domain.Models
{
    using System;
    using System.Collections.Generic;

    public partial class MyClass
    {
        public MyClass()
        {

我想要的是一个受保护的构造函数

    public partial class MyClass
    {
        protected MyClass()
        {

【问题讨论】:

  • 我最初的反应是,我认为数据库优先是不可能的,因为任何刷新模型都会导致您的手动更改被覆盖。
  • 您为什么要这样做?这样就不可能创建此类的实例。您是否试图阻止用户实例化基类?然后检查是否可以在设计器中将基类标记为抽象
  • @PanagiotisKanavos 我正在创建一个需要特定签名的部分类,以便我可以确保我的模型状态有效,例如 MyClass(person person) {this.Person = person}。在这里查看更多解释udidahan.com/2009/06/29/dont-create-aggregate-roots
  • 如果您使用 Code-First 开发代替,您可以这样做:thedatafarm.com/data-access/…
  • @IronMan84 这可以(并且应该)通过修改 t4 模板来完成。那么这些更改将不会被更新覆盖。

标签: c# entity-framework ef-database-first


【解决方案1】:

您可以通过修改创建模型类的 t4 模板来做到这一点。在文件顶部附近寻找这部分:

foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection))
{
    fileManager.StartNewFile(entity.Name + ".cs");
    BeginNamespace(code);
#>
<#=codeStringGenerator.UsingDirectives(inHeader: false)#>
<#=codeStringGenerator.EntityClassOpening(entity)#>
{
<#
    var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity);
    var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity);
    var complexProperties = typeMapper.GetComplexProperties(entity);

    if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any())
    {
#>
    public <#=code.Escape(entity)#>()
    {
<#

并将底线public &lt;#=code.Escape(entity)#&gt;()替换为

protected <#=code.Escape(entity)#>()

此更改将为实体类型创建受保护的构造函数。在文件的下部有一个类似的复杂类型构造,您可能也想修改它。

关于“更新”的词。如果您更新数据库中的模型,这些更改将不会被覆盖。但是,如果你更新 EF,修改t4模板的一个问题是,当你想使用新版本的模板时,你必须再次这样做。

【讨论】:

    【解决方案2】:

    你不能有一个受保护的模型构造函数是不正确的。 可以在某些情况下 - 请参阅 Gert 提供的链接。 http://msdn.microsoft.com/en-us/library/vstudio/dd468057%28v=vs.100%29.aspx 感谢格特的纠正。

    所以你可以通过 T4 改变。

    您仍然认为这是解决问题的最佳方法吗?

    您可以使用验证接口 IValidatableObject 之类的东西 EF 在保存操作期间将调用哪个来验证数据是否正常。

    请记住,在读取数据时,EF 会填充 poco 实例并将引用粘贴在上下文中。 当您填充 POCO 实例时,您可以根据需要触发验证,ef 将在保存之前调用 validate。在 google 上搜索此主题。

    例如

        /// <summary>
        /// Get called everytime  a Validation is triggered on an object. EG MVC model check or  EF save.
        /// </summary>
        public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
    
            // Sample Implementation. 
            var validationResult = new List<ValidationResult>();
    
            // a field cant be null or empty when condition X is true.
            if ( SOME CONDTION that is true   ) {
              validationResult.Add(new ValidationResult(some field is required when...", new List<string>() {"FieldName"}));
              }
    
            return validationResult;
        }
    

    【讨论】:

    • Phil,EF 可以处理受保护的构造函数(甚至是私有的成员),甚至推荐用于某些场景:msdn.microsoft.com/en-us/library/vstudio/…
    • 显然这个文档澄清是更好的信息。谢谢格特。
    • @philsoady 我已经在使用验证问题不仅仅是验证和模型状态之一,业务领域是一个相当复杂的领域,因此为了防止歧义,我正在创建一个意图狂欢的 API。例如,评估总是针对机构进行,因此new assessment() 违反了业务规则。 new assessment(Institution) 有效。更深入的解释lostechies.com/jimmybogard/2010/02/24/…
    猜你喜欢
    • 1970-01-01
    • 2014-04-22
    • 1970-01-01
    • 2016-04-07
    • 2011-05-30
    • 1970-01-01
    • 2021-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多