我正在使用使用EF设计器和.edmx文件(第一个模型)的Entity Framework项目。实体映射到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; }
}
每个实体都映射到数据库中的表。
我有一个代码区域,我想遍历三种不同的资源类型。在该循环中,我无需访问3种实体类型之间不常见的属性。有没有一种方法可以实现此目的,而无需使三个单独的循环以及实体类型之外的所有代码都相同?
我试图在EF设计器中创建一个GenericResource
实体,然后使ResourceX
实体成为其固有对象,但是由于不需要{{1}映射到数据库中的任何内容。我只想创建可以只读方式处理三种资源类型中的任何一种的代码。我不需要创建新的GenericResource
。
也许首先使用模型是不可能的,我需要先转换为代码吗?
答案 0 :(得分:2)
您可以引入一个接口,并将其添加到每个实体的部分类文件中。但是要拥有类继承,您可能必须从现有数据库切换到Code First。顺便说一句,最终您可能不得不从现有的数据库 切换到Code First,因为它更好,并且得到了EF Core的支持。
在代码中,首先,如果您希望数据库忽略基类,则只需将其从DbContext中排除。您将可以在整个代码库中替换子类的实例,但是将没有一个可以查询的DbSet。
答案 1 :(得分:1)
我看到了两种方法:我都不会称之为完美的方法,但也许会有所帮助或有一个改进的想法:
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; }
}
这实际上不是我的数据库,因此我只是在控制台应用程序中对其进行了模拟:
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也不会覆盖它们。