对于我的ASP.NET MVC 2应用程序,我使用Entity Framework 1.0作为我的数据访问层(存储库)。但我决定要回归POCO。当我想要获得带有可选徽标的品牌列表时,我第一次遇到问题。这是我做的:
public IQueryable<Model.Products.Brand> GetAll()
{
IQueryable<Model.Products.Brand> brands = from b in EntitiesCtx.Brands.Include("Logo")
select new Model.Products.Brand()
{
BrandId = b.BrandId,
Name = b.Name,
Description = b.Description,
IsActive = b.IsActive,
Logo = /*b.Logo != null ? */new Model.Cms.Image()
{
ImageId = b.Logo.ImageId,
Alt = b.Logo.Alt,
Url = b.Logo.Url
}/* : null*/
};
return brands;
}
您可以在评论中看到我想要实现的目标。只要Brand
有Logo
,它就可以正常工作,否则你可以通过异常将null分配给非可空类型int(对于Id)。我的解决方法是在POCO类中使用nullable但这不自然 - 然后我不仅要检查我的服务层或控制器和视图中Logo
是否为空,而且主要是Logo.ImageId.HasValue
。如果ID为null
,则拥有非Logo
null
属性是不合理的。
有人能想到更好的解决方案吗?
答案 0 :(得分:1)
只是一个选项
public IQueryable<Model.Products.Brand> GetAll()
{
IQueryable<Model.Products.Brand> brands = from b in EntitiesCtx.Brands
let logo =EntitiesCtx.Logos.First(c=>c.LogoId==b.LogoId);
select new Model.Products.Brand()
{
BrandId = b.BrandId,
Name = b.Name,
Description = b.Description,
IsActive = b.IsActive,
Logo = /*b.Logo != null ? */new Model.Cms.Image()
{
ImageId = logo.ImageId,
Alt = logo.Alt,
Url = logo.Url
}/* : null*/
};
return brands;
}
我想它比方形选择品牌Xlogos更好,而不是我建议使用JOIN 如果您觉得有用,请告诉我们
答案 1 :(得分:0)
一种选择是首先不允许数据库中的空标识,并且在数据库中具有特殊标识id = 0,即无标识徽标。把它放在没有徽标的任何品牌上。即空值模式。
如果您不喜欢使用硬编码ID,请在徽标上创建一个位值“IsNullLogo”,并使用它来初步查找徽标ID(因为它可能在生产中具有不同的ID以进行开发......)
答案 2 :(得分:0)
我有另一个解决方法。因为在某些情况下,Image(Logo属性的类)不能是null
,在某些情况下,我可以决定将一些继承添加到我的Image模型中。这就是我所做的:
public class OptionalImage
{
public long? ImageId
{
get;
set;
}
[DisplayName("Obraz")]
[StringLength(200, ErrorMessage = "Url jest za długi")]
[RegularExpression(@".*\.(jpg|gif|png|jpeg|tif|tiff|JPG|GIF|PNG|JPEG|TIF|TIFF)$", ErrorMessage = "Rozszerzenie pliku jest nieprawidłowe. Dopuszczone to: .jpg, .gif, .png, .jpeg, .tif, .tiff")]
public string Url
{
get;
set;
}
[StringLength(200, ErrorMessage = "Tekst alternatywny jest za długi")]
[DisplayName("Tekst alternatywny")]
public string Alt
{
get;
set;
}
}
public class Image : OptionalImage
{
public new long ImageId
{
get;
set;
}
}
然后我的存储库返回一个可空的Id,仅用于与Image有0..1关系的对象 - 比如Brand。但是具有必需DefaultImage属性的Product将使用不带nullable Id的Image,它对应于数据库和业务逻辑设计。
存储库中的GetAll
方法现在看起来像这样(感谢@omoto提示):
public IQueryable<Model.Products.Brand> GetAll()
{
IQueryable<Model.Products.Brand> brands = from b in EntitiesCtx.Brands
let logo = EntitiesCtx.Images.FirstOrDefault(c => c.ImageId == b.Logo.ImageId)
select new Model.Products.Brand()
{
BrandId = b.BrandId,
Name = b.Name,
Description = b.Description,
IsActive = b.IsActive,
Logo = new Model.Cms.OptionalImage()
{
ImageId = logo.ImageId,
Alt = logo.Alt,
Url = logo.Url
}
};
return brands;
}
对于代替new Model.Cms.OptionalImage()
的产品,我将使用new Model.Cms.Image()
,因为在这种情况下归档的ImageId
数据库的值不能为空,它将正常工作,一切都将是自然的控制器和视图。
我认为这种解决方法非常适合我的需求。如果有人有更好的解决方案,请随时回复。