C# 如何使用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

不久前,当我第一次使用MVC时,我掉进了胖控制器的陷阱。我的第一个应用程序使用EF4制作了我需要的所有模型。我只是把我所有的逻辑放在我的控制器动作中。虽然它有效,但它绝对不是最佳实践方式。为了做到正确,我开始尝试基于EF对象构建模型,努力遵循skinny controller的概念

我在试图找到填充模型的最佳方法时遇到了障碍。有没有一种方法可以运行LINQ查询并让它填充您的模型,而不必迭代属性以设置为另一个类

大概是这样的:

// 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。我使用这个方法已经有一段时间了,它对我很有效。我的错误是,我在解决方案中输入了错误的内容。我已经更新了帖子并添加了评论。