使用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的隐式转换......
答案 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();
}