【问题标题】:Anonymous type and getting values out side of method scope匿名类型和获取方法范围之外的值
【发布时间】:2010-08-28 09:28:00
【问题描述】:

我在 .net 框架 4.0 中构建一个 asp.net 站点,我被困在应该调用 .cs 类并获取查询结果的方法这里是我的方法调用和方法

1:方法调用表单aspx.cs页面:

helper cls = new helper();
  var query = cls.GetQuery(GroupID,emailCap); 

2:帮助类中的方法:

public IQueryable<VariablesForIQueryble> GetQuery(int incomingGroupID, int incomingEmailCap)
    {
        var ctx = new some connection_Connection();
        ObjectSet<Members1> members = ctx.Members11;
        ObjectSet<groupMember> groupMembers = ctx.groupMembers;

        var query = from m in members
                    join gm in groupMembers on m.MemberID equals gm.MemID
                    where (gm.groupID == incomingGroupID) && (m.EmailCap == incomingEmailCap)
                    select new VariablesForIQueryble(m.MemberID, m.MemberFirst, m.MemberLast, m.MemberEmail, m.ValidEmail, m.EmailCap);
                    //select new {m.MemberID, m.MemberFirst, m.MemberLast, m.MemberEmail, m.ValidEmail, m.EmailCap};

        return query ;
    }

我也用 IEnumerable 尝试了上面的代码,但没有任何运气。这是类 VariablesForIQueryble 的代码:

3:将它自己分类为采用匿名类型并将其转换为适当的类型:

public class VariablesForIQueryble
{
    private int _emailCap;
    public int EmailCap
    {
        get { return _emailCap; }
        set { _emailCap = value; }
    }`....................................

4: 和一个构造函数:

 public VariablesForIQueryble(int memberID, string memberFirst, string memberLast, string memberEmail, int? validEmail, int? emailCap)
    {

            this.EmailCap = (int) emailCap;
            .........................

    }

查询结果好像取不回来了,先是告诉我匿名类型的问题,看完后我做了一个类:link text;现在它告诉我不支持参数的构造函数。现在我是一名中级开发人员,是否有一个简单的解决方案或者我必须将我的查询带回 .aspx.cs 页面。

【问题讨论】:

    标签: c#-4.0 entity-framework-4 asp.net-4.0


    【解决方案1】:

    如果您想像这样投影到特定类型的 .NET 类型,您需要使用 .AsEnumerable().ToList() 强制查询实际发生,然后针对 linq to objects 使用 .Select()

    您可以保留您原来的匿名类型以指定您想要从数据库中返回的内容,然后调用.ToList(),然后调用.Select(...) 进行重新投影。

    您还可以通过使用数据库中的 FK 关联在组和成员之间使用实体关联来稍微清理您的代码。那么查询就变得简单多了:

    var result = ctx.Members11.Include("Group").Where(m => m.Group.groupID == incomingGroupID && m.EmailCap == incomingEmailCap);
    

    您仍然需要执行选择以指定要返回的列,然后调用 .ToList() 强制执行,然后再重新投影到您的新类型。

    另一种选择是在您的数据库中创建一个视图,然后将 那个 作为一个实体导入到实体设计器中。

    【讨论】:

    • 感谢骑手,我在这里进行了反思,这是我从中获得代码和想法的链接:stackoverflow.com/questions/874746/… 我正在考虑制作视图,但这太过分了,因为我有多个测试表和我必须从中获取数据的常规表,外键关联的想法很好,但我还是有测试表。我厌倦了 ToList() 方法,它给我带来了问题。最后我不得不去反思。非常感谢您的帮助,先生。
    • 如果您打算使用这样的弱类型,您不妨使用 .NET 4 中的新 dynamic 类型来访问结果对象上的各个字段。 .ToList() 应该可以正常工作:(...query...).ToList().Select(x =&gt; new VariablesForIQuerable(...)).ToList();
    【解决方案2】:

    使用反射解决问题:

    A:查询,不再使用定制的“VariablesForIQueryble”类:

     //Method in helper class 
     public IEnumerable GetQuery(int incomingGroupID, int incomingEmailCap)
            {
    
                var ctx = new some_Connection();
                ObjectSet<Members1> members = ctx.Members11;
                ObjectSet<groupMember> groupMembers = ctx.groupMembers;
    
                var query = from m in members
                            join gm in groupMembers on m.MemberID equals gm.MemID
                            where ((gm.groupID == incomingGroupID) && (m.EmailCap == incomingEmailCap)) //select m;
                            select new {  m.MemberID,  m.MemberFirst,  m.MemberLast, m.MemberEmail,  m.ValidEmail, m.EmailCap };
                            //select new VariablesForIQueryble (m.MemberID, m.MemberFirst, m.MemberLast, m.MemberEmail, m.ValidEmail, m.EmailCap);
                //List<object> lst = new List<object>();
    
                //foreach (var i in query)
                //{
                //    lst.Add(i.MemberEmail);
                //}
                //return lst;
                //return query.Select(x => new{x.MemberEmail,x.MemberID,x.ValidEmail,x.MemberFirst,x.MemberLast}).ToList();
                return query;
            }
    

    B:使用反射捕获对象并转换这些对象的代码

      helper cls = new helper();
      var query = cls.GetQuery(GroupID,emailCap);      
     if (query != null)
                        {
    
                            foreach (var objRow in query)
                            {
    
                                System.Type type = objRow.GetType();
                                int memberId = (int)type.GetProperty("MemberID").GetValue(objRow, null);
                                string memberEmail = (string)type.GetProperty("MemberEmail").GetValue(objRow, null);
        }
        else
        {
        something else....
        }
    

    【讨论】:

    • 我也尝试过这段代码,但我认为反射更好 foreach(var objRow in query){ string[] objects = objRow.ToString().Split(','); foreach (var o in objects.Where(x=>x.Contains("@"))) { if(o.Contains("@")) {do something} }} 但有 2 个循环和更多工作。
    猜你喜欢
    • 1970-01-01
    • 2010-10-22
    • 2013-01-11
    • 2010-11-19
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多