将 entityframework 链接到新的 Sql 数据类型
linking entityframework to a new Sql DataType
我正在使用 ASP.NET MVC5 和 MS SQL 2008 和 EntityFramework 6,在我的应用程序中我有 class 允许客户添加详细信息的经验他们从一个时期到另一个时期的经历:
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; }
}
FromDate 格式将为 MMM yyyy,例如 2009 年 1 月、2010 年 10 月等
ToDate 格式将为 MMM yyyy 或 Present,并且应大于或等于 FromDate 值,例如:
- 从 = 2010 年 1 月,到 = 2014 年 10 月 ==> 已接受
- 从 = 2010 年 1 月,到 = 现在 ==> 已接受
- 从 = 2014 年 10 月,到 = 2014 年 7 月 ==> 拒绝 到日期的值应该大于从日期
我做了class期如下
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;}
}
样本DEMO
在 sql 我创建了以下数据类型
create type Period from nvarchar(8) not null;
问题:
- 如何在 sql 中定义期间?
- 如何告诉 EntityFramework 到 link 句点到 sql 中的数据类型句点?
任何想法将不胜感激
这里有一个解决方法
你的体验class会是这样
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; }
}
在您的周期 class 中更改以下内容,这将是 [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]);
}
}
}
}
在您的映射中,您执行以下操作
modelBuilder.Entity<Experience>()
.Property(t => t.FromDate.Date)
.IsRequired()
.HasMaxLength(8);
modelBuilder.Entity<Experience>()
.Property(t => t.ToDate.Date)
.IsRequired()
.HasMaxLength(8);
要让 entity framework 将字段设为 Period 数据类型,您可以这样做
1-启用迁移
2- add-migration first // 这将创建一个包含数据库和 table 构造的文件 dbmigration
3- 在函数 Up 最后你使用 Sql(@""); 编写以下内容,在这里我将为你放置 sql 语句
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)
并且在 Down 函数中,如果您希望编写代码来删除函数并将 table 字段更改为 return 它们变回 nvarchar(8),最后删除数据类型时期
希望这对您有所帮助
我正在使用 ASP.NET MVC5 和 MS SQL 2008 和 EntityFramework 6,在我的应用程序中我有 class 允许客户添加详细信息的经验他们从一个时期到另一个时期的经历:
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; }
}
FromDate 格式将为 MMM yyyy,例如 2009 年 1 月、2010 年 10 月等 ToDate 格式将为 MMM yyyy 或 Present,并且应大于或等于 FromDate 值,例如:
- 从 = 2010 年 1 月,到 = 2014 年 10 月 ==> 已接受
- 从 = 2010 年 1 月,到 = 现在 ==> 已接受
- 从 = 2014 年 10 月,到 = 2014 年 7 月 ==> 拒绝 到日期的值应该大于从日期
我做了class期如下
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;}
}
样本DEMO
在 sql 我创建了以下数据类型
create type Period from nvarchar(8) not null;
问题:
- 如何在 sql 中定义期间?
- 如何告诉 EntityFramework 到 link 句点到 sql 中的数据类型句点?
任何想法将不胜感激
这里有一个解决方法
你的体验class会是这样
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; }
}
在您的周期 class 中更改以下内容,这将是 [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]);
}
}
}
}
在您的映射中,您执行以下操作
modelBuilder.Entity<Experience>()
.Property(t => t.FromDate.Date)
.IsRequired()
.HasMaxLength(8);
modelBuilder.Entity<Experience>()
.Property(t => t.ToDate.Date)
.IsRequired()
.HasMaxLength(8);
要让 entity framework 将字段设为 Period 数据类型,您可以这样做 1-启用迁移 2- add-migration first // 这将创建一个包含数据库和 table 构造的文件 dbmigration 3- 在函数 Up 最后你使用 Sql(@""); 编写以下内容,在这里我将为你放置 sql 语句
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)
并且在 Down 函数中,如果您希望编写代码来删除函数并将 table 字段更改为 return 它们变回 nvarchar(8),最后删除数据类型时期
希望这对您有所帮助