簡體   English   中英

在WCF服務上公開實體框架

[英]Exposing Entity Framework over WCF Service

我需要一些幫助! 我正在嘗試使用Entity Framework,WCF,MVVM和WPF技術創建我的第一個應用程序。 我是所有人的新手。 所以我使用Entity Framework為我的數據庫創建了一個模型。 然后我創建我的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;
            }
        }
    }
}

我的問題:

  1. 它的問題是不要直接暴露我的數據模型,對吧? 所以我在這里返回類vw_Pedidos分離實體。 這是一種不好的做法嗎?

  2. 我已經閱讀了很多關於DTO和POCO的對象,我應該使用哪個而不是上面的代碼?

  3. 如果我使用DTO或POCO通過WCF進行傳輸,是否必須為每個數據庫對象手動創建DTO? 我是否必須手動為每個數據庫對象創建所有屬性(字段)?

  4. 如果我向數據庫對象添加一個新字段並需要在客戶端上顯示它,我是否必須更新我的EF模型,手動將新字段添加到DTO或POCO對象? 這聽起來像是一場維護噩夢!

  5. 使用EntitiesToDTOs是基於EF對象自動創建DTO的好選擇嗎?

  6. 我可以使用DTO將數據更新回數據庫嗎?

抱歉,有多個問題。 請幫幫我吧! 我正在尋找一種模式,使我易於維護,關注分離代碼。 謝謝!

UPDATE

根據TomTom的建議,我讀了很多關於POCO,EF和Linq to Entities的內容。 之后我重寫了我的整個應用程序。 我將我的代碼划分為5個項目:

1)數據層

2)ModelLayer

3)BusinessLyer

4)WCF服務層

5)WPF客戶端

對於第1層到第5層的通信,我使用POCO T4模板映射到實體框架的POCO類。 為了通過WCF通信第4層和第5層,我想使用自定義類來隱藏客戶端的某些字段(我不想公開整個POCO類)所以我使用linq重寫了過濾函數到實體並投影到IEnumerable:

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();
                }
            }

這是最好的方法嗎? 我可以在濾鏡后進行投影嗎? 謝謝!

它的問題是不要直接暴露我的數據模型,對吧? 所以在這里我將返回類vw_Pedidos的脫離實體。 這是一種不好的做法嗎?

是。

我已經閱讀了很多關於DTO和POCO的對象,我應該使用哪個而不是上面的代碼?

都。 鑒於DTO通常是POCO。 也許你試着理解MEAN這幾個字。 POCO是一個“普通的舊C#對象”(不需要從基類繼承),這對於POCO來說是完全正常的。

如果我使用DTO或POCO通過WCF進行傳輸,我是否必須為每個數據庫對象手動創建DTO? 我是否為每個數據庫對象創建了所有屬性(字段)?

沒有聽說過T4? 這可以編寫腳本。 也就是說,這些通常不是數據庫而是API對象--WCF服務是服務器程序的(公共)前端。

如果我向DB對象添加一個新字段並需要在客戶端上顯示它,我是否必須更新我的EF模型,將新字段手動添加到DTO或POCO對象? 這聽起來像一個維護的nigthmare!

絕對是一個。 如果你不假思索地做事。 說真的,一旦你敲定了基本模型,這不是每15分鍾發生一次的事情。 它還包括前端和邏輯方面的重要工作 - 我的意思是,如果屬性沒用,那么嘿,為什么要把它放進去? 如果它沒用,那么無論如何都要做很多工作。 並且模型可以更新,而不需要重新生成。

哎呀,我通常使用非平凡的數據庫。 在這種情況下,更改不是“重新生成模型”,它還包括“編寫用於版本控制的sql更新腳本”和“測試更新性能”(將字段添加到具有默認值的數十億行表並生成索引可以需要一些時間)。 它仍然不是噩夢,因為這不會每5分鍾發生一次。 MOST的東西不是“添加字段”,而是“程序”。

我可以使用DTO將數據更新回數據庫嗎?

還有什么?

請幫幫我吧! 我正在尋找一種模式,讓我很容易保持,關注分開的代碼

你找不到一個。 這是做出正確妥協的問題。 您似乎高估了項目中發生的變化量。

您可以更好地假設WCF服務是信任邊界和公共API - 非常類似於網站,僅供計算機使用。 您在那里公開的對象必須絕對不符合數據庫內部。 最好單獨生成它們並可能將它們更改為更符合公共API所需的內容 - 而不是將后端實現細節公開給API。

但是,我不得不說,通過訪問數據庫的古老且絕對相反的方式使你的工作變得更加復雜 - 開始使用正確的sql生成器和對象映射器,或者你將在那里進行維護噩夢,不管你怎么做其余的事。 將這樣的SQL字符串放在一起是一個嚴重的“不,永遠”。 並查看如何通過WCF公開OData。 這為您提供了通過URL查詢功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM