Проблема сопоставления отношений внешних ключей (от 1 до 0..1) в Linq to Entities и POCO - PullRequest
0 голосов
/ 14 апреля 2010

Для моего приложения 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, в противном случае исключение можно было присвоить пустому типу int (для Id), не обнуляемому.Мой обходной путь состоял в том, чтобы использовать nullable в классе POCO, но это не естественно - тогда я должен проверить не только, является ли Logo нулевым в моем слое Service или Controllers and Views, но главным образом для Logo.ImageId.HasValue.Неоправданно иметь свойство не null Logo, если идентификатор равен null.

Может кто-нибудь придумать лучшее решение?

Ответы [ 3 ]

1 голос
/ 14 апреля 2010

просто опция

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 Дайте мне знать, пожалуйста, если вы найдете это полезным

0 голосов
/ 14 апреля 2010

У меня есть другой обходной путь для этого. Поскольку в некоторых случаях 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;
    }
}

Тогда мой репозиторий возвращает обнуляемый идентификатор только для объектов, которые имеют отношение 0..1 к Image-like Brand. Но Продукт, имеющий обязательное свойство DefaultImage, будет использовать 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 базы данных, поданной в этом случае, не может быть нулевым, оно будет работать нормально, и все будет естественно в контроллерах и представлениях. Я думаю, что этот вид обходного пути очень хорошо отвечает моим потребностям. Тем не менее, если у кого-то есть лучшее решение, не стесняйтесь отвечать.

0 голосов
/ 14 апреля 2010

Один из вариантов - запретить пустые логотипы в базе данных и иметь специальный логотип id = 0 в базе данных, который является логотипом без логотипа. Поместите это на любой бренд, для которого у вас нет логотипа. то есть шаблон нулевого значения.

Если вам не нравится иметь жестко закодированный идентификатор, создайте битовое значение «IsNullLogo» на логотипе и используйте его для первоначального нахождения идентификатора логотипа (так как он может иметь другой идентификатор при производстве и разработке ...) .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...