EntityFramework database first - type mapping - map binary(8) from SQL to int in C#

∥☆過路亽.° 提交于 2019-12-23 13:30:24

问题


Inside SQL I have table that have primary key as binary(8). When I add that table to my model using Update Model from Database I can see that this column has type=Binary

and in C# I get that column as byte[].

Can I map that column to int?

I know I can create a view with CAST in SQL:

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

but this isn't a solution, because I must be able to write, not just read from that table. I know I can create stored procedure for inserts but I'd like to avoid that.

I'm usinf EntityFramewor 6.1.3.


回答1:


You have 3 different solutions

x Stored procedures but you don't want them.

x Add a not mapped property to your class. The biggest problem about this solution is that you can't make queries using the not mapped property. You have to read all the data to the client then apply the condition on the non mapped property on the client (so your app is not scalable).

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

This query won't work

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

You need to change it in this way

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

The result of this query is that you load all table's records (transfer from dbms to your app) into a list than you take the one you need.

x Create a view (probably an indexed view) and use an INSTEAD OF trigger.




回答2:


I do know why you do not stick to either int or byte in both database structure and c# code of page




回答3:


In my experience the mapping process is quite easy to confuse, especially when updating an existing map. For this reason I'd recommend you use

long CurrentClientId = BitConverter.ToInt64(Rec.ClientId) 

on read and

Rec.ClientId = BitConverter.GetBytes(CurrentClientId) 

on write. You may already have a wrapper to massage records as they are read into an internal structure, this would just be one more step.

Note this doesn't pay any attention to a byte order you may think you have in the byte array, but at least the process will round-trip correctly.




回答4:


You can handle the conversion internally within your model, as follows:

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

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

The caller works with ClientId as a long, but this property is not mapped to the database. The getter and setter simply convert the value to a second property, which is persisted in the ClientId database column name.



来源:https://stackoverflow.com/questions/38653073/entityframework-database-first-type-mapping-map-binary8-from-sql-to-int-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!