C# 如何在实体框架中重写对象的保存行为
我有一门课是这样的:C# 如何在实体框架中重写对象的保存行为,c#,asp.net-mvc-4,entity-framework-5,C#,Asp.net Mvc 4,Entity Framework 5,我有一门课是这样的: public class course { public int CourseID { get; set; } public string Name { get; set; } public Event Schedule {get; set;} //Event is coming from library Dday.iCal } 实体框架无法正确理解如何保存此属性。(我想在保存时将其序列化为字符串,
public class course
{
public int CourseID { get; set; }
public string Name { get; set; }
public Event Schedule {get; set;} //Event is coming from library Dday.iCal
}
实体框架无法正确理解如何保存此属性。(我想在保存时将其序列化为字符串,并在应用程序中使用它时将其作为事件保留。)因此我有两个方法,比如SerializeToString()和DeserializeFromString()。我希望这些方法仅在保存到数据库时应用
我的想法如下。基本上,我尝试将一个单独的属性作为字符串保存在数据库中,事件将被忽略,但它现在不会将任何内容保存到数据库中。我甚至不确定这是一种好的做事方法,还是有更好的方法可以做
public class course
{
public int CourseID { get; set; }
public string Name { get; set; }
private Event _Schedule;
[NotMapped]
public Event Schedule {
get
{
if (!String.IsNullOrEmpty(CourseSchedule))
{
return DeserilizeFromString(CourseSchedule);
}
return new Event();
}
set
{
_schedule = value;
}
}
private string _courseSchedule;
public string CourseSchedule {
get
{
return _courseSchedule;
}
private set
{
if (Schedule != null)
{
_courseSchedule = SerializeToString(Schedule);
}
else
{
_courseSchedule = null;
}
}
}
如果你有一个这样的模型
using (LolEntities context = new LolEntities)
{
...
}
interface ICourseRepository
{
void Add(Course newCourse);
Course FindByID(int id);
}
在应用程序中的某个地方,定义了此模型,通常如下所示:
public partial class LolEntities : ObjectContext
// Model:
public abstract class Person
{
[Key]
public int PersonID { get; set; }
[Required(ErrorMessage = "Last name is required.")]
[Display(Name = "Last Name")]
[MaxLength(50)]
public string LastName { get; set; }
[Required(ErrorMessage = "First name is required.")]
[Column("FirstName")]
[Display(Name = "First Name")]
[MaxLength(50)]
public string FirstMidName { get; set; }
public string FullName
{
get
{
return LastName + ", " + FirstMidName;
}
}
}
(1) 请注意,该类是分部类,因此您可以创建另一个具有相同名称的分部类并重写:
public override int SaveChanges(SaveOptions options)
(2) 或者您可以只捕获事件:
using (DemoAZ_8_0Entities context = new DemoAZ_8_0Entities())
{
context.SavingChanges += ...
}
并在将其发送回数据库之前进行格式化
在您的模型中,只需确保包含一个正确映射到DB中的列的属性。可能会在该逻辑上引入一些抽象,您可以重新创建工作单元和存储库模式,并以更方便的方式添加所需的逻辑。例如,在课程存储库类中,您可以对事件字段序列化和反序列化的add and find方法进行成本分析 我将重点讨论存储库模式,您可以找到关于 整个web数据访问层的设计 例如,要管理课程,您的应用程序应该依赖于这样的ICourseRepository接口
using (LolEntities context = new LolEntities)
{
...
}
interface ICourseRepository
{
void Add(Course newCourse);
Course FindByID(int id);
}
并提供以下实现:
class CourseRepository
{
// DbContext and maybe other fields
public void Add(Course c)
{
// Serialize the event field before save the object
_courses.Add(c); // calling entity framework functions, note
// that '_courses' variable could be an DBSet from EF
}
public Course FindById(int id)
{
var course = /// utilize EF functions here to retrieve the object
// In course variable deserialize the event field before to return it ...
}
}
请注意,EF中的ObjectContext是此模式的一个实现,如果您不打算在将来更改ORM,则可以在EF上重写Save方法
如果您想了解更多关于这种模式的信息,可以访问Martin Fowler网站:
class MyModel
{
public string Text { get; set; }
}
class MyViewModel : MyModel
{
public new string Text
{
get { return base.Text; }
set { base.Text =value.ToUpper(); }
}
}
class Program
{
static void Main(string[] args)
{
MyViewModel mvm = new MyViewModel();
mvm.Text = "hello there";
var s = ((MyModel) mvm).Text; // "HELLO THERE"
}
}
在DataContext中,在controller中使用MyModel使用MyViewModel。asp.net上的一位作者实际上已经实现了您的尝试,几乎达到了一个目标。您可能需要遵循该项目中的几点来开始。指向该项目的链接是 需要注意的是,它确实利用了在实体框架中实现的
DbContext Api
public partial class LolEntities : ObjectContext
// Model:
public abstract class Person
{
[Key]
public int PersonID { get; set; }
[Required(ErrorMessage = "Last name is required.")]
[Display(Name = "Last Name")]
[MaxLength(50)]
public string LastName { get; set; }
[Required(ErrorMessage = "First name is required.")]
[Column("FirstName")]
[Display(Name = "First Name")]
[MaxLength(50)]
public string FirstMidName { get; set; }
public string FullName
{
get
{
return LastName + ", " + FirstMidName;
}
}
}
您的解决方案:
- 模型
- 看法
- 控制器
- 数据访问层(DAL)
课程控制器
、工作类单元
和存储库
进行实现。在本教程结束时,将使用DbContext
实现这些自动属性
,如下所示:
public partial class LolEntities : ObjectContext
// Model:
public abstract class Person
{
[Key]
public int PersonID { get; set; }
[Required(ErrorMessage = "Last name is required.")]
[Display(Name = "Last Name")]
[MaxLength(50)]
public string LastName { get; set; }
[Required(ErrorMessage = "First name is required.")]
[Column("FirstName")]
[Display(Name = "First Name")]
[MaxLength(50)]
public string FirstMidName { get; set; }
public string FullName
{
get
{
return LastName + ", " + FirstMidName;
}
}
}
//存储库:
公共班级学生位置:是否学生位置,可识别
{
私立学校语境;
公共学生定位(学校背景)
{
this.context=上下文;
}
公共IEnumerable GetStudents()
{
返回context.Students.ToList();
}
公立学生GetStudentByID(int id)
{
返回context.Students.Find(id);
}
公共无效插入学生(学生)
{
context.student.Add(学生);
}
公共学生(国际学生ID)
{
Student=context.Students.Find(studentID);
context.student.Remove(学生);
}
公共无效更新学生(学生)
{
context.Entry(student.State=EntityState.Modified;
}
公共作废保存()
{
SaveChanges();
}
私有布尔=假;
受保护的虚拟void Dispose(bool disposing)
{
如果(!this.disposed)
{
如果(处置)
{
context.Dispose();
}
}
这是真的;
}
公共空间处置()
{
处置(真实);
总干事(本);
}
}
//存储库的接口:
公共界面为udentrepository:IDisposable
{
IEnumerable GetStudents();
学生GetStudentByID(int studentId);
无效插入学生(学生);
无效删除学生(国际学生ID);
无效更新学生(学生);
作废保存();
}
//要生成数据库的上下文:
公共课堂背景:DbContext
{
公共数据库集课程{get;set;}
公共数据库集部门{get;set;}
公共数据库集注册{get;set;}
公共DbSet指令器{get;set;}
公共数据库集学生{get;set;}
公共数据库集人物{get;set;}
公共数据库集OfficeSignements{get;set;}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
模式