解决方案 »

  1.   

    我的理解是,尽量在service里处理业务,即service返回的一般就是最终需要的数据源。然后根据action返回的类型再做输出.
      

  2.   

    1.一般都是在业务逻辑层,action只是简单的返回model,至于你说的查询,没用过EF,我们是封装了一个方法,直接调用,根据前台POST的数据生成查询语句
    2.看实际需求可返回IEnumerable<model>  IEnumerable<dynamic> IEnumerable<object[]>  model dynamic object[]等
      

  3.   


    我的观点与你一致。但是在使用EF的过程中我发现,若封装在service中的某方法,在被UI调用时只需要用到实体E的A属性和B属性,那我当然希望封装时只返回A属性和B属性的值,方法内部可以用匿名对象直接实现。但该方法的返回值,就存在问题了呀,难道单独为该方法新建一个模型吗?可若不新建模型,又无法指定方法的返回值。
      

  4.   


    不使用EF的情况下,一切都很明朗。我的问题关键是,EF下嘛。你说的第二点,其中返回动态类型的,我觉得不太好吧,性能降低,以及抛开了ORM本身的优势。
      

  5.   


    你也不要太绝对了。比如说微信团队发布了api,难道调用其api的人都不能用于自己创意的业务、而只能按照微信团队示例的那1、2种程序去设计了?“封装”是个博弈的过程,不是教条。
      

  6.   

    在开发中,服务端可能告诉你“没有功夫在原来4个查询以外,再给你提供第5个你希望的返回格式的查询”,没有功夫给你增加一个新的 model。但是可能过了30天,等你已经“绕开了”了原来纠结的事情而在客户端已经完成了需要的功能,它反而发布了这第5个功能服务,这是常有的事。你说“不允许action怎样怎样、service层不给你暴露整个数据表允许随便增删改查、创建model不太现实”等等,这种问题的“解决”,不纯是一个技术问题。满脑子技术的人,无法解决决策变化问题。
      

  7.   

    理解你的意思。谢谢指点。
    但问题在于,我是在做“原来4个查询”这部分,并不是“使用微信API再写业务”的情况。
    我若是只负责写service,当然是提供“我认为足够的返回格式”,同时为了应付可能多变的需求,我将“IQueryable查询计算器”也提供给调用方。我会认为一般情况下,service中已有指定返回格式的方法,已经足够调用方使用。若实在不满足,还有查询计算器可供使用。
    在以上前提下,作为调用方,若出现“现有返回格式不满足业务需求”,service又没时间给我提供新的方法,我当然会直接用查询计算器自己写业务啦(业务虽然暴露)。我想问的是第一部分,跟第二部分没关系嘛。你这里说到“一个新的model”,那是不是指,我确实应该按需创建新model当返回值?
    再次感谢大神~
      

  8.   

    既然你是做的MVC,那这个道理应该知道,
    一个查询服务应该是提供一种类型的查询,而不是指定具体的哪个表哪个字段,
    它可以满足所有这种类型的查询需求;
    这就好比你的一个View描述的是一种类型的外观逻辑,
    它可以满足所有这种交互模式的界面,而不是特定的某一个界面sql能做到,ado.net也能做到,EF难道会做不到按需输出?
      

  9.   

    个人理解,针对你说的这个问题,EF相比ADO.NET的区别在于EF更倾向于一个强类型的返回值,而不是ADO.NET那种自己解析字段的模式。比如,EF的查询返回一个USER类,那么调用者们都会默契的使用这个类的共有属性去获取数据,这是一种约定。
    但是ADO.NET返回一个datatable,里面的字段要手动去接收,dt.rows[0]["UserName"],这样显然也可以,但是运行时如果结果集里没有这个字段,会在运行时出异常。而且如果你不告诉调用者我的datatable里有这个字段,他也不会知道,或者他只能通过调试去了解这个datatable中都有哪些字段。不知道我说的这些是否有一点正确
      

  10.   

    任何所谓的ORM框架,最后生成的都是SQL语句,使用ado.net去执行,所谓的ORM框架只是封装好了执行数据库的操作,减化了你的代码量。
      

  11.   

    任何所谓的ORM框架,最后生成的都是SQL语句,使用ado.net去执行,所谓的ORM框架只是封装好了执行数据库的操作,减化了你的代码量。
    这个道理谁都懂,我并不是在技术上说这个问题。如果选择了EF,那么先要去理解他的设计思想,然后再去运用,不要纠结于一些小细节。
      

  12.   

    不应该在代码中出现UserName这样的字眼,
    从OOAD的角度说,DataTable也是View(确切地说是数据视图),
    所以在MVC模式下,也是由控制器负责View和DataView之间的渲染和更新的,
    开发人员不需要知道UserName这样具体的信息,
    //比如:要把DataRow中的数据绑定到界面的录入表单,可以这样:
    UpdateView(this.Page, pDR, this.BusinessModel.MethodSave);
      

  13.   

    不应该在代码中出现UserName这样的字眼,
    从OOAD的角度说,DataTable也是View(确切地说是数据视图),
    所以在MVC模式下,也是由控制器负责View和DataView之间的渲染和更新的,
    开发人员不需要知道UserName这样具体的信息,
    //比如:要把DataRow中的数据绑定到界面的录入表单,可以这样:
    UpdateView(this.Page, pDR, this.BusinessModel.MethodSave);
    再次重申,我说的是两个东西是完全不同的设计思想,不要拿技术套好嘛
      

  14.   

    Iqueryable 制定Select()不就行了么 这个可以实现“减”字段的业务返回,
    如果要加字段返回Model 没有找好的办法
    就是重构领域模型 而不是直接使用数据表模型
      

  15.   


    不使用EF的情况下,一切都很明朗。我的问题关键是,EF下嘛。你说的第二点,其中返回动态类型的,我觉得不太好吧,性能降低,以及抛开了ORM本身的优势。
    dynamic性能降低这个还真没去想过,不过看你的回复后特意做了个小测试。代码:            int times = int.Parse(textBox1.Text);            Stopwatch watch1 = Stopwatch.StartNew();
                IList<Test> list = new List<Test>();
                Test test = null;
                for (int i = 0; i < times; i++)
                {
                    test = new Test();
                    test.Search = i;
                    test.Search1 = i;
                    test.Search2 = i;
                    test.Search3 = i;
                    test.Search4 = i;
                    test.Search5 = i;
                    test.Search6 = i;
                    list.Add(test);
                }
                JsonHelper.JsonSerializer(list);
                label1.Text = (string.Format("使用JsonConvert.SerializeObject执行" + times + "次:反射实体类耗时:{0} 毫秒", watch1.ElapsedMilliseconds));            Stopwatch watch2 = Stopwatch.StartNew();
                IList<dynamic> list2 = new List<dynamic>();
                for (int i = 0; i < times; i++)
                {
                    list2.Add(new { 
                        Search = i, 
                        Search1 = i, 
                        Search2 = i,
                        Search3 = i, 
                        Search4 = i, 
                        Search5 = i, 
                        Search6 = i 
                    });
                }
                JsonHelper.JsonSerializer(list2);
                label2.Text = (string.Format("使用JsonConvert.SerializeObject执行" + times + "次:dynamic耗时:{0} 毫秒", watch2.ElapsedMilliseconds));
      

  16.   

    遇到这种情况的时候,把EF抛一边去吧!我的做法就是自己写sql,返回DataTable。用EF是为了方便编程,而不是给自己脖子上套枷锁。
      

  17.   

    对于UI而言,需要有视图解析器,自动按照UI定义取值,可以参考fastCSharp的web视图实现。实例可以参考51nod的web层源代码http://51nod.codeplex.com/SourceControl/latest
    对于纯数据服务,需要定义数据成员集合,可以参考fastCSharp的MemberMap<T>。