Создать базовый тип для существующих рабочих объектов Entity Frame (EF Model First) - PullRequest
0 голосов
/ 16 октября 2018

Я работаю с проектом Entity Framework, в котором используется EF Designer и файл .edmx (сначала модель).Объекты отображаются в базу данных MySQL, и генерируется код модели.У меня есть 3 объекта, которые логически представляют «ресурсы» и разделяют некоторые, но не все поля.Например:

public partial class ResourceA {
    public int ID { get; set; }
    public long ProductID { get; set; }
    public string Path { get; set; }
}

public partial class ResourceB {
    public int ID { get; set; }
    public long ProductID { get; set; }
    public string Label { get; set; }
}

public partial class ResourceC {
    public int ID { get; set; }
    public long ProductID { get; set; }
    public bool Open { get; set; }
    public bool Replacement { get; set; }
}

Каждый из этих объектов сопоставляется с таблицей в базе данных.

У меня есть область кода, где я хочу пройтись по трем различным типам ресурсов.В этом цикле мне не нужно обращаться к свойствам, которые не являются общими для трех типов сущностей.Есть ли способ, которым я могу сделать это без создания трех отдельных циклов со всем идентичным кодом, кроме типов сущностей?

Я попытался создать сущность GenericResource в конструкторе EF, а затем сделать сущности ResourceX присущимиэто, но я запутался, когда дело дошло до отображения, так как мне не нужно GenericResource для сопоставления с чем-либо в базе данных.Я просто хочу создать код, который может обращаться к любому из трех типов ресурсов только для чтения.Мне никогда не нужно создавать новый GenericResource.

Возможно, это невозможно в первую очередь для модели, и мне нужно сначала переключиться на код?

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

Я вижу два подхода: ни один из которых я бы не назвал совершенным, но, возможно, это поможет или поможет улучшить идею:

1) Измените базу данных, чтобы иметь таблицу ресурсов, чтобы ResourceA, Bи C может иметь отношение внешнего ключа.Каждый из ваших классов будет выглядеть следующим образом:

public partial class ResourceA
    {
        public Resource Resource {get; set;}
        public string Path { get; set; }
    }

, и у вас будет таблица, которую EF создаст следующим образом:

public partial class Resource
{
  public int ID {get; set;}
  public long ProductId { get; set; }
}

Другой вариант: будучи частичными классами, вы можете расширять классы.и реализуем их с помощью интерфейса:

Быстрое и немного грязное доказательство концепции:

public interface IResources
{
    Resource GetResource();
}

public partial class ResourceA : IResources
{
    public Resource GetResource()
    {
        return new Resource()
        {
            ID = ID,
            ProductID = ProductID
        };
    }


}
public partial class ResourceB : IResources
{
    public Resource GetResource()
    {
        return new Resource()
        {
            ID = ID,
            ProductID = ProductID
        };
    }
}
public partial class ResourceC : IResources
{
    public Resource GetResource()
    {
        return new Resource()
        {
            ID = ID,
            ProductID = ProductID
        };
    }
}
public class Resource
{
    public int ID { get; set; }
    public long ProductID { get; set; }
}

//These are the "generated" EF partials
public partial class ResourceA
{
    public int ID { get; set; }
    public long ProductID { get; set; }
    public string Path { get; set; }
}

public partial class ResourceB
{
    public int ID { get; set; }
    public long ProductID { get; set; }
    public string Label { get; set; }
}

public partial class ResourceC
{
    public int ID { get; set; }
    public long ProductID { get; set; }
    public bool Open { get; set; }
    public bool Replacement { get; set; }
}

Это на самом деле не для меня в базе данных, поэтому я просто издевался над ней в консолиapplication:

       var A = new ResourceA()
        {
            ID = 15,
            Path = @"C:\Path",
            ProductID = 15001
        };
        var B = new ResourceB()
        {
            ID = 16,
            ProductID = 166101,
            Label = "Ham"
        };
        var C = new ResourceC()
        {
            ID = 188,
            Open = true,
            ProductID = 900014,
            Replacement = false,

        };

        List<IResources> resources = new List<IResources>();
        resources.Add(A);
        resources.Add(B);
        resources.Add(C);

        foreach(var r in resources)
        {
            Console.WriteLine(r.GetResource().ID);
        }

Это работает, но я бы сказал, что это, вероятно, не идеально.Я бы поместил интерфейс и дополнительные классы в отдельный файл на уровне доступа к данным, чтобы EF не перезаписывал их тоже.

0 голосов
/ 16 октября 2018

Вы можете ввести интерфейс и добавить его в частичный файл класса для каждой сущности.Но для наследования классов вам, вероятно, придется переключиться на Code First из существующей базы данных.Кстати, в конечном итоге вам, вероятно, придется переключиться на Code First с существующей базы данных в любом случае , потому что она лучше и поддерживается EF Core.

в Code First, если вы хотите, чтобы база данных не зналабазовый класс, просто исключите его из вашего DbContext.Вы сможете заменять экземпляры подклассов по всей вашей кодовой базе, но у вас не будет ни одного DbSet, к которому вы можете запросить.

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