Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在WCF服务上公开实体框架_C#_.net_Wcf_Entity Framework - Fatal编程技术网

C# 在WCF服务上公开实体框架

C# 在WCF服务上公开实体框架,c#,.net,wcf,entity-framework,C#,.net,Wcf,Entity Framework,我需要一些帮助!我正在尝试使用实体框架、WCF、MVVM和WPF技术创建我的第一个应用程序。我对他们都是新手。因此,我使用实体框架为我的数据库创建了一个模型。然后我创建我的WCF服务类。我已经阅读了近50篇关于EF和WCF服务的文章,现在我对这些都感到困惑。我知道我不应该直接暴露我的模型。目前,我将此代码用作服务合同: namespace Ohmio.DataService { [ServiceContract] public class OhmioService {

我需要一些帮助!我正在尝试使用实体框架、WCF、MVVM和WPF技术创建我的第一个应用程序。我对他们都是新手。因此,我使用实体框架为我的数据库创建了一个模型。然后我创建我的WCF服务类。我已经阅读了近50篇关于EF和WCF服务的文章,现在我对这些都感到困惑。我知道我不应该直接暴露我的模型。目前,我将此代码用作服务合同:

namespace Ohmio.DataService
{
    [ServiceContract]

    public class OhmioService
    {
        [OperationContract]
        public IEnumerable<vw_Pedidos> ListarPedidos(string IDComprobante, bool bEntregados, int Numero = -1, int IDCliente = -1)            
        {
            using (var context = new OhmioTestNet())
            {
                string sqlString="SELECT VALUE cs FROM OhmioTestNet.vw_Pedidos AS cs WHERE cs.ID_Comprobante=='" + IDComprobante + "' AND ";
                if (Numero != -1) sqlString += "cs.Numero=="+ Numero.ToString() +" AND ";
                if (IDCliente != -1) sqlString += "cs.ID_Cliente=="+ IDCliente.ToString()+" AND ";
                if (!bEntregados) sqlString += "cs.Entregado==false AND ";                 
                sqlString =sqlString.Substring(0,sqlString.Length-4);

                ObjectQuery<vw_Pedidos> Pedidos = context.CreateQuery<vw_Pedidos>(sqlString);                
                var result = Pedidos.ToList();
                result.ForEach(e => context.Detach(e));
                return result;
            }
        }

        [OperationContract]
        public IEnumerable<Clientes> GetClientes()
        {
            using (var context = new OhmioTestNet())
            {
                var result = context.Clientes.Where(f => f.Activo == true).ToList();
                result.ForEach(e => context.Detach(e));
                return result;
            }
        }
    }
}
这是最好的方法吗?我可以在滤镜后进行投影吗?谢谢

它的问题是,我不想直接公开我的数据模型,对吗?所以这里 我返回vw_Pedidos类的分离实体。这种做法不好吗

我读了很多关于DTO和POCO对象的书,我应该用哪个来代替上面提到的 密码

两者都有。鉴于DTO通常是POCO。也许你试着理解这些词的意思。POCO是一个“普通的旧C#对象”(不需要从基类继承),这对于POCO来说是完全正常的

如果我使用DTO或POCO通过WCF传输,我是否必须手动为每种传输创建DTO 数据库对象?我是否手动为每个DB对象创建所有属性(字段)

没有。听说过T4吗?这是可以编写脚本的。也就是说,这些通常不是数据库而是API对象——WCF服务是服务器程序的(公共)前端

如果我向DB对象添加了一个新字段,并且需要在客户机上显示它,我需要更新我的字段吗 EF型号,手动将新字段添加到DTO或POCO对象?听起来 就像一个面包师

这绝对是一个。如果你做事不假思索。说真的,一旦你敲定了基本模型,这不是每15分钟发生一次的事情。此外,它还包括一个重要的前端工作和逻辑反正-我的意思是,如果财产是无用的,那么嘿,为什么把它?如果它不是无用的,那无论如何都是一个很大的工作。而且模型可以更新,不需要重新生成

见鬼,我通常使用非平凡的数据库。在这种情况下,更改不是“重新生成模型”,它还包括“编写用于版本控制的sql更新脚本”和“测试更新性能”(使用默认值向数十亿行表中添加字段并生成索引可能需要一些时间)。这仍然不是噩梦,因为这不是每5分钟发生一次。大多数东西不是“添加字段”,而是“程序”

我可以使用DTO将数据更新回数据库吗

还有什么

请帮帮我!我在寻找一种模式,让我找到一个容易掌握的, 关注点分离代码

你找不到。这是一个做出正确妥协的问题。不过,您似乎高估了项目中发生的更改量

您最好假设WCF服务是一个信任边界和公共API—很像一个网站,只是供计算机使用。在那里公开的对象不能完全符合数据库内部结构。与向API公开后端实现细节相比,最好单独生成它们,并可能将它们更改为更符合公共API的需要


我不得不说,尽管如此,您访问数据库的陈旧且完全相反的方式使您的工作变得更加复杂-开始使用适当的sql生成器和对象映射器,否则无论您如何执行其余操作,您都将面临维护噩梦。像这样组合SQL字符串是一个严肃的“不,永远不会”。并查看如何通过WCF公开OData。通过URL提供查询功能。

Big subject;)不是这样的答案,但我会从这里开始,在你进入MVVM部分之前,它很好地解释了实体框架的WCF谢谢你的答案!我已经读过这篇文章,这正是我的观点。在本文中,创建一个DataContract类来访问Product EF对象,然后手动在DataContract类和EF类之间逐个映射所有字段!这听起来很疯狂!事实上,您有两个类别具有相同的属性,需要手动更新!这是一个鬼脸!这不是一个更好的方法吗?你的更新看起来不错(尽管你做了两次相同的if和filter检查,可能只是一个输入错误)。我个人会先做任何过滤,这样你就不会浪费CPU时间创建你将要扔掉的对象,但这只是一个小优化。它的旧版本位于。这篇文章的作者还有一本书,谢谢你的回答。因此,我完全理解并同意您的看法,即我的服务公开的数据将不同于从数据库中获取的数据层,因此直接公开我的EF对象是个坏主意。我想一个选项是创建一个datacontract DTO类并手动映射我想要公开的字段,对吗?另外,我需要你的最后一部分的澄清。为什么你说我的过滤代码是“过时的,完全相反的”?请问有没有更好的方法使用可选的辅助过滤器过滤数据?ThksI实际上会研究LINQ集成投影;)重新仿古-示例代码是通过字符串操作手动构造SQL。那是过时的。Linq可以很好地做到这一点(IQueryable可以有多个where子句),您可以通过WCF直接公开IQueryable。谢谢汤姆的回答。我相信你的回答在技术上是优秀的,但作为一个新手,有些事情我不明白。你向我澄清我不该做什么:我不想暴露我的EF对象。那我该怎么办呢?如何公开WCF服务上的数据?我应该创建DTO(或POCO)和手动映射字段吗?我看到了关于LINQ和IQueryable DTO的思考,但在那里谈到了clien
public IEnumerable<PedidosList> Pedidos_Listar(string sComprobante, Clientes MyCliente = null, DateTime? dDesde = null, DateTime? dHasta = null, bool bCumplidos = false)
            {           
                using (var context = new OhmioEntities())
                {
                    IEnumerable<PedidosList> query =
                        from Pedidos in context.Pedidos
                        join Clientes in context.Clientes on Pedidos.ID_Cliente equals Clientes.ID_Cliente
                        where Pedidos.ID_Comprobante == sComprobante                    
                        select new PedidosList {ID_Pedido = Pedidos.ID_Pedido, Fecha=Pedidos.Fecha, Aprobado=Pedidos.Aprobado, Bruto=Pedidos.Bruto, Cliente=Clientes.RazonFantasia, 
                            FechaEntrega=Pedidos.FechaEntrega, Neto=Pedidos.Neto, Numero=Pedidos.Numero, Observaciones=Pedidos.Observaciones, Entregado=Pedidos.Entregado, ID_Cliente=Pedidos.ID_Cliente };

                    if (MyCliente != null) query = query.Where(i => i.ID_Cliente == MyCliente.ID_Cliente);
                    if (MyCliente != null) query = query.Where(i => i.ID_Cliente == MyCliente.ID_Cliente);
                    if (dDesde != null && dHasta != null) query = query.Where(i => i.Fecha >= dDesde && i.Fecha <= dHasta);
                    if (bCumplidos == false) query = query.Where(i => i.Entregado == false);                
                    return query.ToList();
                }
            }