2015-01-01 5 views
7

Ich benutze ASP.NET MVC5 und MS SQL 2008 und EntityFramework 6, in meiner Anwendung habe ich eine Klasse Erfahrungen, die den Kunden erlauben, Details ihrer Erfahrungen aus Periode bis Periode hinzufügen:Verknüpfung von Entityframework zu einem neuen Sql DataType

public class Experience 
{ 
    public int Id { get; set; } 
    public string Title { get; set; } 
    public string Company { get; set; } 
    public string FromDate { get; set; } 
    public string ToDate { get; set; } 
    public string Description { get; set; } 
} 

wird das Format MMM yyyy Fromdate, Beispiel Jan 2009, 2010, ... etc Oktober wird das ToDate sein Format entweder MMM yyyy oder vorhanden sein und sollte zum Beispiel als oder gleich dem Wert Fromdate größer sein:

  1. Von = Jan 2010, Bis = Oct 2014 ==>Akzeptierte
  2. Von = Januar 2010, Gegenwart == To => Akzeptiert
  3. Von = Oktober 2014, To = == Juli 2014>Abgelehntder Wert sollte eine aktuelle größer ist als die von Datum

ich machte die Klasse Periode folgen, wie

public class Period: IComparable 
{ 
    public Period() 
    { 
     this.Month="Present"; 
    } 

    public Period(string Month,int Year) 
    { 
     this.Month=Month; 
     this.Year=Year; 
    } 

    public int CompareTo(object obj) 
    { 
     if(obj==null) 
      return 1; 
     Period period = obj as Period; 
     if (period != null) 
     { 
      if(this.Month=="Present" && period.Month=="Present") 
       return 0; 
      else if(period.Month=="Present") 
       return -1; 
      else if(this.Month=="Present") 
       return 1; 
      else 
      { 
       DateTime date; 
       DateTime periodDate; 
       if(!DateTime.TryParse(string.Format("01 {0} {1}",Month,Year),out date)) 
        throw new ArgumentException("Instance is not a valid Period!");    
       if(!DateTime.TryParse(string.Format("01 {0} {1}",period.Month,period.Year),out periodDate)) 
        throw new ArgumentException("Object is not a valid Period!"); 
       return date.Date.CompareTo(periodDate.Date); 
      } 
     } 
      else 
       throw new ArgumentException("Object is not a Period"); 
    } 

    public override int GetHashCode() 
    { 
     if(this==null) 
      return 0; 
     else 
     { 
      DateTime date; 
      if(!DateTime.TryParse(string.Format("01 {0} {1}",Month,Year),out date)) 
       throw new ArgumentException("Instance is not a valid Period!");   
      return date.GetHashCode(); 
     } 
    } 

    public override bool Equals(object obj) 
    { 
     return this.CompareTo(obj)==0; 
    } 

    public static bool operator==(Period left, Period right) 
    { 
     return left.Equals(right); 
    } 

    public static bool operator!=(Period left, Period right) 
    { 
     return !(left==right); 
    } 

    public static bool operator<(Period left, Period right) 
    { 
     return left.CompareTo(right)<0; 
    } 

    public static bool operator>(Period left, Period right) 
    { 
     return left.CompareTo(right)>0; 
    } 

    public override string ToString() 
    { 
     if(string.IsNullOrWhiteSpace(Month)) 
      return string.Empty; 
     else if(Month=="Present") 
      return Month; 
     else 
      return string.Format("{0} {1}",Month,Year); 
    } 

    public string Month{get; set;} 
    public int Year{get; set;} 
} 

Probe DEMO

in SQL habe ich den folgenden Datentyp

create type Period from nvarchar(8) not null; 

Fragen:

  1. Wie kann ich die Zeit in den SQL definieren?
  2. Wie kann ich EntityFramework sagen, Zeitraum mit dem Datentyp Zeitraum in SQL verknüpfen?

wird jede Idee

+0

ich es nicht glaube, wird dazu beitragen, ist jede Validierung für diese in ef.You können es durch benutzerdefinierte Validierung mit für Client und Server. Benötigen Sie auch eine Client-Validierung? Sonst können Sie einfach ein paar Code im Server hinzufügen oder einen neuen Filter dafür hinzufügen. – Binod

+0

Ich denke, es gibt einen Weg, ich bin sicher, da EF ist eine großartige Technologie und sicher, dass sie diese Details nicht verpassen, ich warte, um zu sehen, ob jemand dies bestätigen kann oder ich werde enttäuscht sein – mah

+0

versuchen, zu verwenden, vergleichen Attribut erben von ValidationAttribute . – Binod

Antwort

1

hier eine Abhilfe zu erkennen, wie es zu tun

Ihre Erfahrung Klasse wie diese in der Periode Klasse den folgenden

public class Experience 
{ 
    public int Id { get; set; } 
    public string Title { get; set; } 
    public string Company { get; set; } 
    public Period FromDate { get; set; } 
    public Period ToDate { get; set; } 
    public string Description { get; set; } 
} 

Änderung sein, die das sei ein [ComplexType]

// change the folllowing 
[NotMapped] 
public string Month{get; set;} 
[NotMapped] 
public int Year{get; set;} 

// add this property to use it for EntityFramework mapping 
public string Date 
{ 
    get 
    { 
     return ToString(); 
    } 
    set 
    { 
     if (!string.IsNullOrEmpty(Date)) 
      { 
       if (Date == "Present") 
        Month = "Present"; 
       else 
       { 
        var split = Date.Split(' '); 
        Month = split[0]; 
        Year = Convert.ToInt32(split[1]); 
       } 
      } 
     } 
    } 

in Ihrem Mapping Sie die folgenden

modelBuilder.Entity<Experience>() 
       .Property(t => t.FromDate.Date) 
       .IsRequired() 
       .HasMaxLength(8); 

modelBuilder.Entity<Experience>() 
      .Property(t => t.ToDate.Date) 
      .IsRequired() 
      .HasMaxLength(8); 

, um den Entity Framework zu lassen die Felder Zeitraum Datentyp zu machen, Sie können dies tun, 1- enable-Migration 2- Add-Migration ersten // dies erstellen eine Datei dbmigration, der die Datenbank und Tabellenkonstruktion 3- in der Funktion Up Sie am Ende hat schreiben die sql folgenden mit (@ „“) ;, hier werde ich die sQL-Anweisungen für Sie zusammengestellt

create function CheckPeriod(@period nvarchar(8)) -- this function will make sure that Period is valid 
returns bit 
as 
begin 
    declare @month nvarchar(3) 
    if (@period is null) 
     return 0 
    if(@period = 'Present') 
     return 1; 
    set @month=substring(@period,0,3) 
    if(@month in ('Jan','Feb','Mar','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')) 
     return 1; 
    return isdate(@period); 
end 

create function CheckValidity(@right as nvarchar(8),@left as nvarchar(8)) -- this function will compare FromDate to ToDate and return valid if ToDate>FromDate 
returns bit 
as 
begin 
    if(@right='Present') 
     return 0; 
    if(@left='Present' and cast(@right as date)>=getdate()) 
     return 0; 
    if(@left='Present') 
     return 1; 
    if(cast(@left as date)>cast(@right as date)) 
     return 1; 
    return 0; 
end 

exec sp_addtype 'Period','nvarchar(8)','NOT NULL' 


alter table Experiences alter column FromDate Period 
alter table Experiences alter column ToDate Period 

alter table Experiences 
add constraint FromDateIsPeriod check (dbo.CheckPeriod(FromDate)=1) 

alter table Experiences 
add constraint ToDateIsPeriod check (dbo.CheckPeriod(ToDate)=1) 

alter table Experiences 
add constraint PeriodValidity check (dbo.CheckValidity(FromDate,ToDate)=1) 

und in die Down - Funktion, wenn Sie möchten, dass Sie den Code schreiben, um die Funktionen zu löschen und die Tabellenfelder sie als nvarchar (8), um wieder zurück und schließlich den Datentyp Periode

Hoffnung fallen diese Sie

Verwandte Themen