2016-07-29 106 views
4

SQL内部我有主键为二进制(8)的表。当我使用Update Model from Database该表添加到我的模型,我可以看到,这列了type = BinaryEntityFramework数据库优先 - 类型映射 - 将二进制(8)从SQL映射到C#中的int

enter image description here

,并在C#中,我得到的是列byte[]

我可以将该列映射到int吗?

我知道我可以在SQL创建一个视图与CAST

SELECT 
    Client_Id, 
    CAST(Client_Id AS INT) AS NewClient_Id, 
    * /*other columns*/ 
FROM 
    dbo.Clients 

,但这不是解决办法,因为我必须能写,不只是从该表中读取。我知道我可以为插入创建存储过程,但我想避免这种情况。

我是usinf EntityFramewor 6.1.3。

+0

你是否也会尝试将一夸脱放入一个品脱罐中? 'binary(8)'包含8个字节。 C#中的“int”包含4个字节。你在这里看到问题吗? –

+0

@Damien_The_Unbeliever对不起,如果我写了不正确的东西,但我试图让它工作。我认为,如果我可以在SQL中执行CAST,那么EF可能会为我执行该操作。我可以通过代码将'byte []'转换为int,但我认为EF具有这种内置,我只是不知道如何打开或配置它。 – Misiu

+0

你可以写信给一个视图。但是,您需要为视图提供触发器,以便将值转换回来。也是二进制8是一个长期的IIRC – Mark

回答

0

我不知道你为什么不坚持int或字节

0

以我的经验映射过程是很容易混淆的两个数据库结构和C#代码,更新现有的地图时尤其如此。出于这个原因,我建议你使用

long CurrentClientId = BitConverter.ToInt64(Rec.ClientId) 
上读

Rec.ClientId = BitConverter.GetBytes(CurrentClientId) 

上写。你可能已经有了一个包装器来按摩记录,因为它们被读入内部结构中,这只是一个步骤。

请注意,这并不关注您可能认为在字节数组中存在的字节顺序,但至少该过程将正确地往返。

0

您可以在模型中在内部处理的转换,具体如下:

[NotMapped] 
    public long ClientId 
    { 
     get { return BitConverter.ToInt64(this.ClientIdBytes, 0); } 
     set { this.ClientIdBytes = BitConverter.GetBytes(value); } 
    } 

    [Column("ClientId")] 
    public byte[] ClientIdBytes { get; set; } 

主叫方与客户端Id工作作为一项长期的,但是这个属性不会映射到数据库。 getter和setter只是将该值转换为第二个属性,该属性保留在ClientId数据库列名中。

+0

这将使用数据库优先方法吗? – Misiu

+0

这是唯一的方法,但是您不能使用ClientId字段(即context.MyTable.Where(e => e.ClientId == 1))将LINQ写入实体查询。你必须阅读所有的表格,而不是应用条件(即context.MyTable.ToList()。其中​​(e => e.ClientId == 1)) – bubi

+0

谢谢你的建议,但我想避免加载整个表到内存中 – Misiu

2

你有3种不同的解决方案

x存储过程,但你不想要它们。

x将一个未映射的属性添加到您的类。这个解决方案最大的问题是你不能使用未映射的属性进行查询。您必须将所有数据读取到客户端,然后将条件应用于客户端上的非映射属性(这样您的应用程序才具有可伸缩性)。

[NotMapped] 
public long LongClientId 
{ 
    get { return BitConverter.ToInt64(this.ClientId, 0); } 
    set { this.ClientId = BitConverter.GetBytes(value); } 
} 

这个查询将行不通

context.MyDbSet.Where(m => m.LongClientId == 12).ToList(); 

您需要更改它以这种方式

context.MyDbSet.ToList().Where(m => m.LongClientId == 12); 

此查询的结果是,你加载所有表的记录(从转移dbms添加到您的应用程序中)放到列表中,而不是您需要的那个。

x创建视图(可能是索引视图)并使用INSTEAD OF触发器。

+0

我在GitHub的EF知识库中创建了问题,因为我想在EF6和EF内核中找不到目前可能的问题。我可能会选择第三种解决方案,因为我不想将整个表加载到内存中('ToList'就是这样)。存储过程也会这样做,所以现在查看看起来像是最好的解决方案。我会把这个开放,也许有更好的解决方案。 – Misiu