2013-06-11 2 views
0

Используя API EF5 Fluent, кто-нибудь знает, возможно ли иметь бинарный столбец в базе данных, но длинный в C#? Когда мы помещаем длинный объект, мы всегда получаем ошибки EF во время выполнения (невозможно выполнить сопоставление). Если мы поместим байт [], тогда все работает (двоичный в db обычно означает тип byte [] в коде .NET). Мы не можем изменить тип столбца базы данных, чтобы он не был решением.EF5 Fluent API byte array to long

Вот что мы в конечном итоге делает:

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 длинный (а не байт []) и то же самое для DBID тогда мы не нужно было бы делать весь этот redondant код. Поэтому это невозможно, EF жалуется во время выполнения (поскольку тип столбца db двоичный). Но SQL Server обрабатывает неявное преобразование из двоичного кода в BigInt ...

ответ

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); 
} 

EDIT:

Ладно я понимаю вашу проблему. Вам нужен 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(); 
     } 
+1

Привет, мы отдаем себе отчет Bitconverter, но это не представляется возможным назвать «стандартной» функции в запросе Linq. Для этого вам нужно сначала использовать анонимный тип, перечислить его, а затем запрограммировать на нужный тип – Fabien

+0

, можете ли вы показать свой запрос? – aiapatag

+0

Где находится свойство byte [], которое вы пытаетесь преобразовать в long? – aiapatag