我可以将查询结果投影到EF生成的模型吗?

时间:2014-04-19 07:37:43

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

我有一个类似下面的方法:

 public IEnumerable<CountryEF> GetAllCountry( )
    {


        using (Context context  = new Context() )
        {

            List<CountryEF> countries = context.COUNTRY.Select(c =>

                 new CountryEF()
                 {
                     ID = c.ID,
                     Description = c.DESCRIPTION,
                     CURRENCYEF = c.CURRENCYEF
                 }

            ).ToList<CountryEF>();

            return countries;
        }


    }

其中COUNTRYEF是由实体框架生成的模型类,如下所示:

public partial class COUNTRYEF
{
    public COUNTRYEF()
    {

    }

    public string ID { get; set; }
    public string DESCRIPTION { get; set; }
    public virtual CURRENCY CURRENCYEF { get; set; }

}

当我这样做时,我得到了例外。所以作为一个后备,我必须创建另一个类,它只是上面类的复制粘贴,如下所示:

    public class COUNTRYVM //view model class
    {
        public COUNTRYVM()
        {

        }

        public string ID { get; set; }
        public string DESCRIPTION { get; set; }
        public virtual CURRENCY CURRENCYEF { get; set; }

    }

然后我的查询就像这样:

    public IEnumerable<CountryVM> GetAllCountry( )
    {


        using (Context context  = new Context() )
        {

            List<CountryVM> countries = context.COUNTRY.Select(c =>

                 new CountryVM()
                 {
                     ID = c.ID,
                     Description = c.DESCRIPTION,
                     CURRENCYEF = c.CURRENCYEF
                 }

            ).ToList<CountryVM>();

            return countries;
        }

    }

以上解决方案运行良好。但是我真的想将像public partial class COUNTRYEF这样的实体框架生成的模型类复制到像public class COUNTRYVM这样的东西。我真的不想做代码重复。

有什么可能的解决方案? 匿名属性也不。我曾尝试过以下解决方案:

   public IEnumerable GetAllCountry( )
    {


        using (Context context  = new Context() )
        {

            var countries = context.COUNTRY.Select(c =>

                 new  //Anonymous Projection 
                 {
                     ID = c.ID,
                     Description = c.DESCRIPTION,
                     CURRENCYEF = c.CURRENCYEF
                 }

            ).ToList();

            return countries;
        }

    }

但是我无法在我的视图和控制器中访问ID,描述和CurrencyEF !!

1 个答案:

答案 0 :(得分:0)

实体框架不允许在其投影中创建实体的类。与它有关的事情很难跟踪它应该跟踪哪些实体。我使用的工作。而不是复制和粘贴类只是将其子类化。

public partial class CountryEFSub : CountryEF
{
}


public IEnumerable<CountryEF> GetAllCountry( )
{

    using (Context context  = new Context() )
    {

        return context.COUNTRY.AsNoTracking().Select(c =>

             new CountryEFSub()
             {
                 ID = c.ID,
                 Description = c.DESCRIPTION,
                 CURRENCYEF = c.CURRENCYEF
             }

        ).AsEnumerable();
    }
}

这种欺骗在EF 5中有效。我没有将它用于任何其他版本。另请注意,您可以将方法类型保留为CountryEF。

您可以创建一个T4来为您创建所有子类。此外,如果您需要有关投影的帮助,我相信AutoMapper现在支持IQueryable。否则,您可以手动或使用expresison树来编写投影。