从第一个数据库asp.net mvc中的密钥查找第二个数据库中的数据

时间:2015-09-28 12:24:33

标签: c# asp.net-mvc entity-framework

在控制器中为列表运行get方法时出现以下错误:

  

指定的LINQ表达式包含对与不同上下文关联的查询的引用。

调试控制器后,是生成错误的orderby语句

方法是:

    public ActionResult OwnerList()
    {                              
        var owners = (from s in db.Owners                       
                     orderby Peopledb.Posts.FirstOrDefault(x => x.PostId == s.PostId).PostName
                     select s).ToList();

        var viewModel = owners.Select(t => new OwnerListViewModel
        {
             Created = t.Created,
             PostName = Peopledb.Posts.FirstOrDefault(x => x.PostId == t.PostId).PostName,
             Dormant = t.Dormant,
             OwnerId = t.OwnerId,
        });
        return PartialView("_OwnerList", viewModel);
    }

第一个数据库中的所有者类是dbcontext = IARContext:

public class Owner
{
    public int OwnerId { get; set; }

    [Column(TypeName = "int")]
    public int PostId { get; set; }

    [Column(TypeName = "bit")]
    public bool Dormant { get; set; }

    [Column(TypeName = "datetime2")]
    public DateTime Created { get; set; }

    public virtual ICollection<Asset> Assets { get; set; }

    public People.Models.Post Post { get; set; }
}

第二个数据库中的Post类是dbcontext = PeopleContext:

public class Post
{
    public int PostId { get; set; }

    [StringLength(50)]
    [Column(TypeName = "nvarchar")]
    public string PostName { get; set; }

    [Column(TypeName = "bit")]
    public bool Dormant { get; set; }

    [StringLength(350)]
    [Column(TypeName = "nvarchar")]
    public string Description { get; set; }

    public virtual ICollection<Contract> Contracts { get; set; }

    public virtual ICollection<Owner> Owners { get; set; }
}

我在IAR数据库中显示所有者列表时,我试图从人员数据库中的Post查找PostName

2 个答案:

答案 0 :(得分:1)

对我来说,这个消息很清楚:你混合了两个上下文。这是不可能的。这几乎意味着要创建一个hadhoc dblinq。

解决方案是:

  • 全球背景
  • 按代码分隔(如果上下文无法全球化):

对我来说你应该

public ActionResult OwnerList()
{                              
    var owners = (from s in db.Owners                                   
                 //can't order from here without a dbling/global context
                 select s);
    //may be a where is missing here ?

    List<DAOSomeName> viewModel = owners.Select(t => new DAOSomeName
    {
         Created = t.Created,             
         Dormant = t.Dormant,
         OwnerId = t.OwnerId,
    });// .ToList(); the materialization is done by the following foreach

    //until here, no run to the db, no data transfered.

    foreach (DAOSomeName m in viewModel ) {
        m.PostName = Peopledb.Posts.Where(x => x.PostId == t.PostId).
            Select(x => x.PostName).FirstOrDefault();
        //this way you also handle the null case pointed by Trevor
    }

    //please note that this way, yout view model is not anymore linked
    //to the context, except if one property is a navigation property

    return PartialView("_OwnerList", viewModel.OrderBy(x => x.PostName));
}

public class DAOSomeName {
    public DateTime Created {get; set;}
    //Dormant, OwnerId, PostName...
}  

答案 1 :(得分:0)

通过修改我的控制器:

    public ActionResult OwnerList()
    {
        var posts = new List<People.Models.Post>(Peopledb.Posts);
        var owners = new List<Owner>(db.Owners);
        var ownerposts = (from c in posts
                         join d in owners on c.PostId equals d.PostId
                         orderby c.PostName
                         select new OwnerPost { OwnerId = d.OwnerId, PostName = c.PostName, Created = d.Created, Dormant = d.Dormant }).ToList();

        var viewModel = ownerposts.Select(t => new OwnerListViewModel
        {
            Created = t.Created,
            PostName = t.PostName,
            Dormant = t.Dormant,
            OwnerId = t.OwnerId,
        });

        return PartialView("_OwnerList", viewModel);
    }

并添加OwnerPost类:

public class OwnerPost
{
    public int OwnerId { get; set; }

    public string PostName { get; set; }

    public bool Dormant { get; set; }

    public DateTime Created { get; set; }
}

我解决了问题