如何使用Entity Framework将存储过程的结果映射到具有不同命名参数的实体

bab*_*thy 23 entity-framework entity-framework-4 ef-code-first

我正在尝试使用Entity Framework创建一个基本示例来将SQL Server存储过程的输出映射到C#中的实体,但该实体具有不同(友好)的名称参数,而不是更隐蔽的名称.我也试图用Fluent(即非edmx)语法来做这件事.


什么有用......

存储过程返回名为:UT_ID,UT_LONG_NM,UT_STR_AD,UT_CITY_AD,UT_ST_AD,UT_ZIP_CD_AD,UT_CT的值

如果我创建这样的对象......

public class DBUnitEntity
{
    public Int16 UT_ID { get; set; }
    public string UT_LONG_NM { get; set; }
    public string UT_STR_AD { get; set; }
    public string UT_CITY_AD { get; set; }
    public string UT_ST_AD { get; set; }
    public Int32 UT_ZIP_CD_AD { get; set; }
    public string UT_CT { get; set; } 
}
Run Code Online (Sandbox Code Playgroud)

和像这样的EntityTypeConfiguration ......

public class DbUnitMapping: EntityTypeConfiguration<DBUnitEntity>
{
        public DbUnitMapping()
        {
            HasKey(t => t.UT_ID);
        }
}
Run Code Online (Sandbox Code Playgroud)

...我在DbContext的OnModelCreating中添加,然后我可以从数据库中获取实体,这很好,使用此....

var allUnits = _context.Database.SqlQuery<DBUnitEntity>(StoredProcedureHelper.GetAllUnitsProc);
Run Code Online (Sandbox Code Playgroud)

但是,什么行不通

如果我想要这样的实体,有更友好的名字......

public class UnitEntity : IUnit
{
    public Int16 UnitId { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public Int32 Zip { get; set; }
    public string Category { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

和像这样的EntityTypeConfiguration ......

    public UnitMapping()
    {
        HasKey(t => t.UnitId);

        Property(t => t.UnitId).HasColumnName("UT_ID");
        Property(t => t.Name).HasColumnName("UT_LONG_NM");
        Property(t => t.Address).HasColumnName("UT_STR_AD");
        Property(t => t.City).HasColumnName("UT_CITY_AD");
        Property(t => t.State).HasColumnName("UT_ST_AD");
        Property(t => t.Zip).HasColumnName("UT_ZIP_CD_AD");
        Property(t => t.Category).HasColumnName("UT_CT");
    }
Run Code Online (Sandbox Code Playgroud)

当我尝试获取数据时,我收到带有消息的System.Data.EntityCommandExecutionException ....

"数据读取器与指定的'DataAccess.EFCodeFirstSample.UnitEntity'不兼容.类型成员'UnitId'在数据读取器中没有相应的列具有相同的名称."

如果我将"存储过程命名"属性添加到实体,它就会抱怨下一个"未知"属性.

"HasColumnName"不能像我期望/希望它在这个代码优先的存储过程流畅的EF风格吗?


更新:

尝试使用DataAnnotations(来自ComponentModel的Key和来自EntityFramework的Column)... ala

public class UnitEntity : IUnit
{
    [Key]
    [Column("UT_ID")]
    public Int16 UnitId { get; set; }
    public string Name { get; set; }
Run Code Online (Sandbox Code Playgroud)

这确实消除了DBUnitEntity对数据库相同命名(即只添加[Key]属性)的任何EntityTypeConfiguration的需要,但对于具有与数据库不匹配的属性名称的实体没有做任何事情(相同的错误)像之前一样).

我不介意在模型中使用ComponentModel Annotations,但如果我能帮助它,我真的不想在模型中使用EntityFramework Annotations(不想将Model绑定到任何特定的数据访问框架)

Ser*_*gey 21

实体框架代码第一本书(第155页):

SQLQuery方法总是尝试基于属性名称的列到属性匹配...无,列到属性名称匹配不考虑任何映射.例如,如果已将DestinationId属性映射到Destination表中名为Id的列,则SqlQuery方法将不使用此映射.

因此,在调用存储过程时不能使用映射.一种解决方法是修改存储过程以返回带有与对象属性名称匹配的每列的别名的结果.

Select UT_STR_AD as Address From SomeTable 等等