从数据库更新模型(数据库优先)

时间:2011-07-20 07:36:18

标签: entity-framework asp.net-mvc-3

我正在使用MVC3 VS2010和EF4.1,我使用SQL Server创建了我的数据库,然后将其导入MVC3 Web应用程序。

我在这里遇到了一个挑战,当我从数据库更新模型时,我确实丢失了所有模型文件修改,例如,如果我在某些模型中使用属性进行验证,或者所有这些都被新模型属性覆盖

是否有从数据库更新模型而不丢失模型的信息?

OR

我应该在哪里定义模型验证,而不是直接使用模型的文件?

4 个答案:

答案 0 :(得分:11)

更新:由于这仍然比较受欢迎,我已经创建了一篇博文。

http://jnye.co/Posts/19/adding-validation-to-models-created-by-entity-framework-database-first-c

如果要验证模型,而不使用viewModel,请使用partial类来定义验证属性。例如:

假设您有一个类似

的模型
public class User {
    public string Name { get; set; }
}

如果你想在其上放一个字符串长度验证器,你需要创建一个部分类并使用MetadataTypeAttribute(它存在于System.ComponentModel.DataAnnotations中)

以下类应在各自独立的文件中定义, NOT 与自动生成的模型放在同一个文件中。

[MetadataTypeAttribute(typeof(UserMetadata))]
public partial class User {
}

然后,您可以在UserMetadata类中定义验证,如下所示

public class UserMetadata{
    [StringLength(50)]
    public string Name {get; set;}
}

修改

我刚刚发现这篇文章更详细地解释了解决方案 http://themonitoringguy.com/tips-tricks/validating-microsoft-entity-framework-objects-c-mvc/

答案 1 :(得分:3)

不,每次都会重新生成文件。

所有类都定义为部分类,因此您可以使用MetadataTypeAttribute轻松添加DataAnnotations。

假设您有一个User类定义如下:

public partial class User {
    public string Name {get;set;}
}

创建IUser界面

public interface IUser {
   [Required]
   [DisplayName("User name")]
   string Name {get;set;}
}

然后扩展User类以指定将IUser用作元数据。

[MetadataType(typeof(IUser))]
public partial class User {} //Empty class body

答案 2 :(得分:1)

任何设计师的第一条规则是:它生成任何无法修改的代码,因为下次更新设计器中的任何内容时它将被完全删除。

所有生成的类都是部分的,因此您可以创建自己的部分部分并将自定义逻辑放在那里。您显然无法将属性添加到自动生成的部件中定义的属性。在数据注释的情况下,可以通过buddy classes或自定义T4模板,该模板将包含您自己的逻辑,以决定在代码生成期间应添加哪些数据注释。这两种情况都被认为是一种不好的做法,因为每个视图应该有单独的视图模型,并且该视图需要完全验证。

答案 3 :(得分:1)

检查MainClass的名称空间与Partial相同,并具有相同的属性。那是我的解决方法。

示例:

元数据:随处创建此

public class FormMetadata
{
    public int Id { get; set; }
    public string Description { get; set; }
    public Nullable<bool> IsEnable { get; set; }
    public Nullable<System.DateTime> CreationDate { get; set; }
    public int CompanieId { get; set; }
    public string RegularExpression { get; set; }

    public virtual ICollection<Field> Fields { get; set; }
    [JsonIgnore]
    public virtual Company Company { get; set; }
}

MainClass

namespace Transactions.Model
{
  public partial class Form
  {
      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
      public Form()
      {
          this.Fields = new HashSet<Field>();
      }  
      public int Id { get; set; }
      public string Description { get; set; }
      public Nullable<bool> IsEnable { get; set; }
      public Nullable<System.DateTime> CreationDate { get; set; }
      public int CompanieId { get; set; }
      public string RegularExpression { get; set; }
      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
      public virtual ICollection<Field> Fields { get; set; }
      public virtual Company Company { get; set; }
  }
}

部分使用MetadataType

namespace Transactions.Model
{
    [MetadataTypeAttribute(typeof(FormMetadata))]
    public partial class Form
    {
    }
}

如果在同一个NameSpace中创建类局部类时遇到问题?不用担心:

  1. 创建文件夹
  2. 在此文件夹中创建Class Partial
  3. 在MainClass相同的地方更改命名空间