EF5 Fluent API字节数组为long

时间:2013-06-11 07:07:20

标签: c# api entity-framework-5 fluent

使用EF5 Fluent API有谁知道数据库中是否有二进制列,但C#中有一个长列?当我们在实体中放置一个long时,我们总是在运行时遇到EF错误(无法执行映射)。如果我们放一个byte []然后一切正常(db中的二进制文件通常意味着.NET代码中的byte []类型)。我们无法更改数据库列类型,因此它不是解决方案。

以下是我们最终要做的事情:

from l in LeadDataRepository.GetAll()
select new { // we need an anonymous type here we use Linq to Entities
    FirstName = l.FirstName,
    LastName = l.LastName,
    CompanyName = l.CompanyName,
    CityId = l.CityId,
    DbID = l.DbId
 }).ToList() // once listed we use Linq to objects
.Select(l => new LeadListingViewModel() { // our real class
    FirstName = l.FirstName,
    LastName = l.LastName,
    CompanyName = l.CompanyName,
    CityId = l.CityId.ToLong(), // here we use our extension method on byte[] which converts to long
    DbID = l.DbId.ToLong()
})

如果我们能够在实体中指定CityId是long(而不是byte [])并且对于DbId是相同的那么我们就不必执行所有这些redondant代码。因此这是不可能的,EF在运行时抱怨(因为db列类型是二进制)。但SQL Server处理从二进制到bigint的隐式转换......

1 个答案:

答案 0 :(得分:0)

您可以使用BitConverter

static void Main(string[] args)
{
    long number = 1234167237613;

    //convert to byte array
    byte[] bytes = BitConverter.GetBytes(number);

    //vice-versa
    long number2 = BitConverter.ToInt64(bytes, 0);

    Console.WriteLine(number == number2);
}

修改

好的,我明白你的问题。您需要的是一个Fluent API,可以自动将byte[]转换为long,反之亦然。很遗憾,Fluent API无法为您进行转换。

但幸运的是,您可以拥有一个表示byte[](二进制)属性的包装器属性,该属性仅供您的C#代码使用。您只需将此包装器属性标记为[NotMapped],以使其不属于您的数据库架构。然后,每次需要修改此二进制数据时,您只需使用该包装器属性。

这是一个例子;

namespace EntityFrameworkByteToLong.Models
{
    public class SomeEntity
    {
        public int Id { get; set; }

        public byte[] SomeBytes { get; set; } //this is the column in your DB that can't be changed

        [NotMapped]
        public long SomeByteWrapper //your wrapper obviously
        {
            get
            {
                return BitConverter.ToInt64(SomeBytes, 0);
            }
            set
            {
                SomeBytes = BitConverter.GetBytes(value);
            }
        }
    }
}

然后您可以通过以下方式使用该包装器:

        using(var ctx = new UsersContext())
        {
            SomeEntity s = new SomeEntity();
            s.SomeByteWrapper = 123861234123;

            ctx.SomeEntities.Add(s);
            ctx.SaveChanges();
        }