C# 如何使用Linq从实体框架设置此参数
不久前,当我第一次使用MVC时,我掉进了胖控制器的陷阱。我的第一个应用程序使用EF4制作了我需要的所有模型。我只是把我所有的逻辑放在我的控制器动作中。虽然它有效,但它绝对不是最佳实践方式。为了做到正确,我开始尝试基于EF对象构建模型,努力遵循skinny controller的概念 我在试图找到填充模型的最佳方法时遇到了障碍。有没有一种方法可以运行LINQ查询并让它填充您的模型,而不必迭代属性以设置为另一个类 大概是这样的:C# 如何使用Linq从实体框架设置此参数,c#,asp.net-mvc,linq,entity-framework-4,C#,Asp.net Mvc,Linq,Entity Framework 4,不久前,当我第一次使用MVC时,我掉进了胖控制器的陷阱。我的第一个应用程序使用EF4制作了我需要的所有模型。我只是把我所有的逻辑放在我的控制器动作中。虽然它有效,但它绝对不是最佳实践方式。为了做到正确,我开始尝试基于EF对象构建模型,努力遵循skinny controller的概念 我在试图找到填充模型的最佳方法时遇到了障碍。有没有一种方法可以运行LINQ查询并让它填充您的模型,而不必迭代属性以设置为另一个类 大概是这样的: // from EF model built from databas
// from EF model built from database
public class MyEFObject
{
public int ID {get; set;}
public string Name {get; set;}
public string Title {get; set;}
}
public class MyObjectModel : MyEFObject
{
private Entities _data = new Entities();
public MyObjectModel(int? id)
{
if(id.HasValue) // get an existing record
{
this = _data.MyEFObjects.Where(m => m.ID.Equals(id)).Single();
// or populate right out of the query
_data.MyEFObjects.Where(m => m.ID.Equals(id))
.Select(o => new {
this.ID = o.ID,
this.Name = o.Name,
this.Title = o.Title
});
}
else
{
// set defaults for a new MyObjectModel
}
}
public void Save()
{
// takes the current object and saves changes
}
}
public class MyObjectModel : MyEFObject
{
public void Save(int? id, MyObjectModel model)
{
var data = new Entities();
MyEFObject foo;
if(id.HasValue)
{
foo = data.MyEFObjects.Where(e => e.ID.Equals(id.Value)).Single();
}
else
{
foo = new MyEFObject();
}
foo.Name = model.Name;
foo.Title = model.Title;
if(!id.HasValue)
{
data.MyEFObjects.AddObject(foo);
}
data.SaveChanges();
}
}
我知道您可以向EF实体对象添加函数,但我喜欢在一个调用保存方法中创建或更新所有绑定的函数。如果我必须从本质上重新创建我已经从EF对象中获得的东西,我看不出弄乱模型有什么意义。如果我只是在接受填充对象的类上有一个方法,那么我的视图的可用模型的概念就被否定了。你可以做的是有一个域模型、ef模型和适配器。我认为这可以保持代码非常干净,并很好地分离映射逻辑
//Domain model to decouple from EF
public class MyObjectModel
{
public int ID {get; set;}
public string Name {get; set;}
public string Title {get; set;}
}
//Auto generated Entity Framework class
public class MyEFObject
{
public int ID {get; set;}
public string Name {get; set;}
public string Title {get; set;}
}
//Adapter responsible for mapping your data to your domain model
public class MyObjectModelAdapter : MyEFObject
{
public MyObjectModelAdapter(MyEFObject entity)
{
if(entity != null)
{
this.ID = entity.ID;
this.Name = entity.Name;
this.Title = entity.Title;
}
else
{
// set defaults for a new MyObjectModel
}
}
}
那么基本用法是:
new Entities().MyEFObjects.ToList().Select(x => new MyObjectModelAdapter(x));
或
如果您特别需要MyObjectModel列表,则可以执行以下操作:
new Entities().MyEFObjects.ToList().Select(x => new MyObjectModelAdapter(x) as MyObjectModel);
或
当然,您不想像那样将实体上下文链接在一起,这只是为了显示用法。Slauma是对的。LINQ to实体不会接受它。我尝试了几个版本的帖子,结果发现我自己乱七八糟。我已经达到了可以设置实例值的程度,但到那时EF不会注册已经做出的更改,从而破坏了整个目的。也许有办法做到这一点,但到目前为止,让它发挥作用的步骤似乎有些过火 我的结局是这样的:
// from EF model built from database
public class MyEFObject
{
public int ID {get; set;}
public string Name {get; set;}
public string Title {get; set;}
}
public class MyObjectModel : MyEFObject
{
private Entities _data = new Entities();
public MyObjectModel(int? id)
{
if(id.HasValue) // get an existing record
{
this = _data.MyEFObjects.Where(m => m.ID.Equals(id)).Single();
// or populate right out of the query
_data.MyEFObjects.Where(m => m.ID.Equals(id))
.Select(o => new {
this.ID = o.ID,
this.Name = o.Name,
this.Title = o.Title
});
}
else
{
// set defaults for a new MyObjectModel
}
}
public void Save()
{
// takes the current object and saves changes
}
}
public class MyObjectModel : MyEFObject
{
public void Save(int? id, MyObjectModel model)
{
var data = new Entities();
MyEFObject foo;
if(id.HasValue)
{
foo = data.MyEFObjects.Where(e => e.ID.Equals(id.Value)).Single();
}
else
{
foo = new MyEFObject();
}
foo.Name = model.Name;
foo.Title = model.Title;
if(!id.HasValue)
{
data.MyEFObjects.AddObject(foo);
}
data.SaveChanges();
}
}
我不想处理我的模型的两个实例,但它可以工作,我有我的精益控制器操作。它不能处理EF,因为在LINQ to Entities中不支持投影到构造函数中带有参数的类型。@Slauma感谢您指出,我的解决方案中有一个错误。为了首先执行查询,应该先调用ToList。我使用这个方法已经有一段时间了,它对我很有效。我的错误是,我在解决方案中输入了错误的内容。我已经更新了帖子并添加了评论。