簡體   English   中英

存儲過程返回復雜類型,我使用 AutoMapper 將其映射到我的模型,但未設置外鍵對象

[英]Stored procedure returns complex type, I use AutoMapper to map it to my model but foreign key objects do not get set

我使用 AutoMapper 從我的 DataLayer(EF6 DbFirst AutoGenerated 層)映射到我的 ModelLayer(Pocos/Dtos)。 我感到困惑的一件事是,當使用存儲過程時,它們會返回一個復雜的對象,例如 Customer_GetCustomers_Result,因此我必須使用 AutoMapper 將其映射到我的 CustomerPoco 並且丟失了諸如 Customer.Address 的外鍵對象屬性,因為它們不在我的復雜類型中.

這是我的 CustomerPoco 的示例:

public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Phone { get; set; }
    public string Fax { get; set; }
    public string Website { get; set; }
    public int AddressId { get; set; }

    // THESE END UP NOT GETTING SET
    public List<CustomerContact> Contacts { get; set; }
    public Address Address { get; set; }
}

在我的 GetCustomers 存儲過程中,可以說我做了一些簡單的事情:SELECT * FROM CUSTOMER。 它返回一個復雜的對象 context.Customer_GetCustomers_Result。 然后我必須將這個復雜的對象映射到我的 CustomerPoco。 聯系人和地址未設置。 我應該怎么做?

這是我對客戶的映射:

    CreateMap<Customer, Model.Customer>()
        .ForMember(dest => dest.Contacts, opt => opt.MapFrom(src => src.CustomerContacts));

    CreateMap<Customer_GetCustomers_Result, Model.Customer>();

這實際上可能是一個糟糕的問題。 我相信如果我真的想使用存儲過程來返回我的列表,我將需要進行連接並在我的選擇中實際返回 Address 的屬性,例如... a.Address1、a.Address2 等。 那么有沒有辦法從這里將它們映射到 Model.Customer.Address 即使它們都被拆分為單獨的屬性?

我認為您在這里有兩個單獨的問題需要解決。 第一個是如何讓存儲過程返回並將所有數據綁定到您的 EF 復雜類型。 這里(博客)這里(CodeProject)有幾篇文章應該會有所幫助。 本質上,編寫 sproc 以返回多個結果集,並編寫幾行代碼以前進到下一個結果集並將其讀入上下文。

要從 AutoMapper 獲得所需的映射,您還需要為用作屬性的每種類型添加映射(例如,從 EF 'Address' 類型到 POCO 'Address' 類型的映射)。

這實際上相當簡單,但您可能需要設置一些 AutoMapper 配置。 您的存儲過程實際上只能返回扁平化的結果,但您仍然可以傳遞所有關系的所有字段。 如果您想幾乎免費配置,您實際上只需要讓您的存儲過程以扁平格式返回屬性名稱。 例如, AddressCity而不是City之類的東西。 如果正在映射的對象,你有一個像一個屬性AddressCity ,並會映射對象,你有一個導航屬性Address ,它本身有一個屬性City ,AutoMapper會自動在適當的填補了這一。 如果您不想或不能更改存儲過程返回的列名,那么您只需配置 AutoMapper:

AutoMapper.Mapper.CreateMap<Customer_GetCustomers_Result, Custom>()
    .ForMember(dest => dest.Address, opts => opts.MapFrom(src => new Address
    {
        City = src.City,
        // etc.
    });

如果您有更復雜的場景,例如可枚舉的導航屬性,則此方法將不起作用。 在這種情況下,最好的辦法是分多個步驟進行,這樣您就可以使用一個存儲過程來檢索主要對象以及可以用它展平的所有內容。 這樣,您就可以映射到您想要的類型。 然后,使用單獨的存儲過程根據主對象的 id 或其他內容查找可枚舉項,並將它們映射到先前映射對象上的可枚舉屬性。

public IEnumerable<object> sample()
   {


        using (SqlConnection con = new SqlConnection(connStr))
        {
            DataTable dt = new DataTable();
            SqlCommand cmd = new SqlCommand("proedurename", con);
            cmd.CommandType = CommandType.StoredProcedure;
            if (cmd.Connection.State != ConnectionState.Open)
                cmd.Connection.Open();

            var retObject = new List<dynamic>();
            using (var dataReader = cmd.ExecuteReader())
            {
                while (dataReader.Read())
                {
                    var dataRow = new ExpandoObject() as IDictionary<string, object>;
                    for (var iFiled = 0; iFiled < dataReader.FieldCount; iFiled++)
                    {
                        dataRow.Add(
                            dataReader.GetName(iFiled),
                            dataReader.IsDBNull(iFiled) ? null : dataReader[iFiled] // use null instead of {}
                        );
                    }

                    retObject.Add((ExpandoObject)dataRow);
                }
            }
            return retObject;
        }

    }

暫無
暫無

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

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