2014-01-03 3 views
0

Я переписываю веб-приложение с PHP на MVC.NET на C#. С помощью обратной инженерии я создал модель базы данных EF.Auto generate view model

Поскольку исходное приложение содержит множество таблиц (сущности), я хочу, чтобы как-то pregenerate MVC ViewModels из базы данных (или лицо из EF) с атрибутами, такими как

[Required] 
[Display(Name = "columnName")] 
[StringLength(100)] 
... 
... 

просто примерно базами данных, поэтому я могу редактировать некоторые атрибуты viewmodel для использования в представлении.

Кто-нибудь сделал что-то подобное или знал о каком-либо расширении к VS или подключаемому модулю?

Действительно благодаря

+0

Я не уверен, что вы после. Если вы действительно после создания 'ViewModels', я бы предостерег, что между вашими таблицами базы данных и вашими« ViewModels »существует очень слабая связь. Как правило, 'Views' требуют объединения данных из нескольких таблиц, файлов cookie, ввода пользователем. Это не то, что обычно можно предсказать и, следовательно, создать заранее. –

ответ

1

«инструмента», чтобы сделать это, являются так называемые шаблоны t4, что является функция, которую можно использовать в визуальной студии, где вы можете в основном генерировать все, что вам нужно.

Хотя это не так легко отлаживать эти шаблоны, так что будьте осторожны;)

: редактировать: Если вы не хотите, чтобы положить слишком много усилий в этом сами, вы можете использовать 3 инструменты сторонних которых построить framework вокруг t4, например http://www.devart.com/entitydeveloper/, который является отличным инструментом и может генерировать контроллеры + представления из вашей модели EF или NHibernate. Или, по крайней мере, вы можете взглянуть на сборку в шаблонах и отредактировать их ...

0

Я создал визуальный студийный шаблон t4 для этого. Он будет захватывать файл, как это:

using MicroMvvm; 

namespace MyApplication 
{ 
    [Bindable] 
    public partial class MyApplication 
    { 
     [Bindable] 
     private string _ipAdress; 

     [Bindable] 
     private MyChild _child; 

     public MyApplication() 
     { 
      IpAdress = "ip adress test"; 
      Child = new MyChild(this, ""); 
     } 

     [Bindable] 
     void AddDot() 
     { 
      IpAdress += "."; 
     } 

     [Can] 
     bool CanChangeChild() 
     { 
      return IpAdress.Trim().Length != 0; 
     } 

     [Bindable] 
     void ChangeChild() 
     { 
      Child = new MyChild2(this); 
     } 
    } 
} 

И создать этот файл:

using System; 
using System.ComponentModel; 
using System.Windows.Input; 
using MicroMvvm; 

namespace MyApplication 
{ 

    public partial class MyApplication : INotifyPropertyChanged 
    { 
     [field: NonSerialized] 
     public event PropertyChangedEventHandler PropertyChanged; 

     private void RaisePropertyChanged(String propertyName) 
     { 
      var handler = PropertyChanged; 
      if (handler == null) return; 
      var e = new PropertyChangedEventArgs(propertyName); 
      handler(this, e); 
     } 

     public String IpAdress 
     { 
      get { return _ipAdress; } 
      set 
      { 
       _ipAdress = value; 
       RaisePropertyChanged("IpAdress"); 
      } 
     } 
     public MyChild Child 
     { 
      get { return _child; } 
      set 
      { 
       _child = value; 
       RaisePropertyChanged("Child"); 
      } 
     } 
     public ICommand AddDotCommand { get { return new RelayCommand(AddDot, null); } } 
     public ICommand ChangeChildCommand { get { return new RelayCommand(ChangeChild, CanChangeChild); } } 
    } 

} 

Это шаблон, вам необходимо изменить «MyApplication» с именем проекта, который содержит объекты, которые требуется морфировать в viewmodels.

<#@ template debug="false" hostspecific="false" language="C#" #> 
<#@ assembly name="System.Core" #> 
<#@ import namespace="System.Linq" #> 
<#@ import namespace="System.Reflection" #> 
<#@ import namespace="System.Text" #> 
<#@ import namespace="System.Collections.Generic" #> 
<#@ output extension=".cs" #> 
<#@ assembly name="$(SolutionDir)MicroMvvm\bin\Debug\MicroMvvm.dll" #> 
<#@ assembly name="$(SolutionDir)MyApplication\bin\Debug\MyApplication.dll" #> 
<#@ import namespace="MyApplication" #> 
using System; 
using System.ComponentModel; 
using System.Windows.Input; 
using MicroMvvm; 

namespace MyApplication 
{ 
<# 
    var assembly = typeof(MyApplication).Assembly; 

    var types = new HashSet<Type>(assembly.GetTypes().Where(type => Attribute.GetCustomAttribute(type, typeof(MicroMvvm.Bindable)) != null)); 
    var skip = new HashSet<Type>(types.Where(type => types.Contains(type.BaseType))); 

    foreach (Type type in types) 
    { 
     if (Attribute.GetCustomAttribute(type, typeof(MicroMvvm.Bindable)) == null) 
      continue; 

#> 
    public partial class <#=type.Name#> <#=skip.Contains(type) ? "" : ": INotifyPropertyChanged"#> 
    { 
<# 
     if (!skip.Contains(type)) 
     { 
#> 
     [field: NonSerialized] 
     public event PropertyChangedEventHandler PropertyChanged; 

     private void RaisePropertyChanged(String propertyName) 
     { 
      var handler = PropertyChanged; 
      if (handler == null) return; 
      var e = new PropertyChangedEventArgs(propertyName); 
      handler(this, e); 
     } 

<# 
     } 
     foreach(FieldInfo fieldInfo in type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Instance)) { 
      if (!Attribute.IsDefined(fieldInfo, typeof(MicroMvvm.Bindable))) 
       continue; 
      if (!fieldInfo.Name.StartsWith("_")) 
       continue; 
      string fieldName = fieldInfo.Name.Substring(1); 
      fieldName = char.ToUpper(fieldName[0]) + fieldName.Substring(1); 

#>  public <#=fieldInfo.FieldType.Name#> <#=fieldName#> 
     { 
      get { return <#=fieldInfo.Name#>; } 
      set 
      { 
       <#=fieldInfo.Name#> = value; 
       RaisePropertyChanged("<#=fieldName#>"); 
      } 
     } 
<# 
     } 

     foreach(MethodInfo method in type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Instance)) { 
      if (!Attribute.IsDefined(method, typeof(MicroMvvm.Bindable))) 
       continue; 

      MethodInfo canMethod = null; 
      foreach(MethodInfo searchMethod in type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Instance)) { 
       if (Attribute.IsDefined(searchMethod, typeof(MicroMvvm.Can)) && ("Can" + method.Name).Equals(searchMethod.Name)) 
        canMethod = searchMethod; 
      } 

#>  public ICommand <#=method.Name#>Command { get { return new RelayCommand(<#=method.Name#>, <#= canMethod == null ? "null" : canMethod.Name #>); } } 
<# 
     } 
#> 
    } 
<# 
    } 
#> 
} 

Она также нуждается в рамках MicroMvvm, и два Bindable и Can System.Attribute в. Это значительно сокращает код плиты котла, который вам нужно написать. Но его немного грубо по краям.

+0

HI это замечательно, но отображение свойств во время итерации объектов EF не всегда работает – transformer