Linq 查询抛出实体或复杂类型无法在 linq to entity 中构造,即使我仅使用 select new { ..} 删除 class 名称也是如此

Linq query throws entity or complex type cannot be constructed in a linq to entity, even when i remove the class name just using select new { ..}

我正在阅读这样的文章:Error: The entity or complex type cannot be constructed in a LINQ to Entities query

所以我认为在我的查询中我应该从 select new rpm_scrty_rpm_usr{.. 更改为 select new { ...

然后我从

的错误信息中走出来
  • ex {"The entity or complex type 'ConAppTester.rpm_scrty_rpm_usr' cannot be constructed in a LINQ to Entities query."} System.Exception {System.NotSupportedException}

改为不编译和获取

Error 3 Cannot implicitly convert type System.Collections.Generic.List<AnonymousType#1> to System.Collections.Generic.List<ConAppTester.rpm_scrty_rpm_usr> C:\dev\RLISAdmin\ConAppTester\DbMethods.cs 51 11 ConAppTester

方法

public List<rpm_scrty_rpm_usr> GetUsers()
{
    var queryAllUsers = (from ru in db.rpm_usr
                              join ei in db.emp_info on ru.wwid equals ei.wwid
                              let cdis_eml = ei.dmn_addr + ";"
                              where ru.inact_ind == "N" && ei.inact_ind == "N" && ei.dmn_addr != null
                              orderby ei.dmn_addr
                              select new rpm_scrty_rpm_usr{
                                  usr_id = ru.usr_id,
                                  usr_lnm = ru.usr_lnm,
                                  usr_pwd = ru.usr_pwd,
                                  usr_fnm = ru.usr_fnm,
                                  wwid = ru.wwid,
                                  apprvr_wwid = ru.apprvr_wwid,
                                  chg_dtm = ru.chg_dtm,
                                  chg_usr_id = ru.chg_usr_id,
                                  dflt_ste_id = ru.dflt_ste_id,
                                  cre_dtm = ru.cre_dtm,
                                  cre_usr_id = ru.cre_usr_id,
                                  lst_pwd_chg_dtm = ru.lst_pwd_chg_dtm,
                                  lst_accs_dtm = ru.lst_accs_dtm,
                                  email_id = ru.email_id,
                                  inact_ind = ru.inact_ind,
                                  salt = ru.salt,
                                  tel = ru.tel
                              }).ToList();
    return queryAllUsers;
}

上下文参考

private RPMContext db = new RPMContext();

上下文文件

public DbSet<rpm_scrty_rpm_usr> rpm_usr { get; set; }
public DbSet<rpm_scrty_emp_info> emp_info { get; set; }

普科斯

public class rpm_scrty_rpm_usr
{
    [Key]
    public string usr_id { get; set; }

    public string usr_fnm { get; set; }
    public string usr_lnm { get; set; }
    public string usr_pwd { get; set; }
    public string email_id { get; set; }
    public string wwid { get; set; }
    public string tel { get; set; }
    public int dflt_ste_id { get; set; }
    public DateTime? lst_pwd_chg_dtm { get; set; }
    public DateTime? lst_accs_dtm { get; set; }
    public string apprvr_wwid { get; set; }
    public string inact_ind { get; set; }
    public string cre_usr_id { get; set; }
    public DateTime? cre_dtm { get; set; }
    public string chg_usr_id { get; set; }
    public DateTime? chg_dtm { get; set; }
    public string salt { get; set; }
}

其他poco

public class rpm_scrty_emp_info
{
    [Key]
    public string idsid { get; set; }

    public string wwid { get; set; }
    public string dmn_addr { get; set; }
    public string inact_ind { get; set; }
}

你的问题是,正如错误消息所说,L2E 不知道你的实体。它的工作方式是在您枚举查询之前不会发生任何事情。在您的情况下,调用 ToList() 即可。届时,数据库将尝试执行查询,发现它不知道您的实体,并给出异常。

您需要做的是以这样一种方式构建您的查询,即在数据库上执行的位(即在您枚举之前)不包含对您的实体的任何引用,然后在您枚举之后(届时结果将在内存中,并与数据库分离)您可以创建实体。

尝试以下...

var queryAllUsers = (from ru in db.rpm_usr
                     join ei in db.emp_info on ru.wwid equals ei.wwid
                     let cdis_eml = ei.dmn_addr + ";"
                     where ru.inact_ind == "N" && ei.inact_ind == "N" && ei.dmn_addr != null
                     orderby ei.dmn_addr
                     select ru)
                     .ToList()
                     .Select(ru => new rpm_scrty_rpm_usr {
                       usr_id = ru.usr_id,
                       usr_lnm = ru.usr_lnm,
                       usr_pwd = ru.usr_pwd,
                       usr_fnm = ru.usr_fnm,
                       wwid = ru.wwid,
                       apprvr_wwid = ru.apprvr_wwid,
                       chg_dtm = ru.chg_dtm,
                       chg_usr_id = ru.chg_usr_id,
                       dflt_ste_id = ru.dflt_ste_id,
                       cre_dtm = ru.cre_dtm,
                       cre_usr_id = ru.cre_usr_id,
                       lst_pwd_chg_dtm = ru.lst_pwd_chg_dtm,
                       lst_accs_dtm = ru.lst_accs_dtm,
                       email_id = ru.email_id,
                       inact_ind = ru.inact_ind,
                       salt = ru.salt,
                       tel = ru.tel
                     };

如您所见,括号内没有提及您的实体,因此调用 ToList() 时,数据库不会有问题。然后在内存中创建实体。

上面的代码是基于这样一个事实,在我看来,您好像只是选择 ru 作为查询结果。如果您需要来自相关实体的数据,那么您需要进行两次选择,一次与之前一样(但不引用实体),一次在调用 ToList() 以创建实体之后进行。

顺便说一下,let cdis_eml = ei.dmn_addr + ";" 行似乎不需要,所以您可以将其删除。

希望对您有所帮助。由于我不熟悉你的数据库结构,所以很难知道这是否正是你想要的,所以如果你有任何问题,请随时回复。