[英]How can I use a generic type with entity framework core?
If I have a domain model that looks something like this:如果我有一个看起来像这样的域模型:
public class Foo<T> {
public Guid Id { get; set; }
public string Statement { get; set; }
public T Value { get; set; }
}
I want to use it for built in Data Types (string, int, etc...) as well as date.我想将它用于内置数据类型(字符串、整数等...)以及日期。 I want to use it like:我想像这样使用它:
var foo = new Foo<string>();
foo.Value = "Hey";
how can I persist this to a database using EF Core?如何使用 EF Core 将其保存到数据库中?
I imagine the database table would look like我想数据库表看起来像
| Id | Statement | ValueAsString | ValueAsDecimal | ValueAsDate | ValueAsInt |
| 1 | NULL | "Hey" | | | |
| 2 | NULL | | 1.1 | | |
you should still have a class.你应该还有一堂课。 Your class Foo
should be abstract.你的类Foo
应该是抽象的。 So you would get":所以你会得到“:
public abstract class Foo<T> {
public Guid Id { get; set; }
public string Statement { get; set; }
public T Value { get; set; }
}
then your implementation class would be:那么你的实现类将是:
public class Orders: Foo<Order> {
}
now you have your Orders
class with your generic type which can be stored.现在您拥有了可以存储的具有泛型类型的Orders
类。
If you want to persist different values types to the database in a single table similar to the one in your question, you can do it like this:如果您想将不同的值类型持久保存到数据库中类似于您问题中的表的单个表中,您可以这样做:
public interface IHasValue<T> {
T Value { get; set; }
}
public abstract class Foo {
public Guid Id { get; set; }
public string Statement { get; set; }
}
public class Foostring : Foo, IHasValue<string> {
string Value { get; set; }
}
public class FooInt : Foo, IHasValue<int> {
int Value { get; set; }
}
In your DbContext
class add properties:在您的DbContext
类中添加属性:
public DbSet<FooString> FooStrings { get; set: }
public DbSet<FooInt> FooInts { get; set; }
You can set the column names for the table in the OnModelCreating
method of your DbContext
:您可以在表中设置的列名OnModelCreating
你的方法DbContext
:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// include the base class so a single table is created for the hierarchy
// rather than a table for each child class
modelBuilder.Entity<Foo>().ToTable("Foos");
// Specify the column names or you will get weird names
modelBuilder.Entity<FooString>().Property(entity => entity.Value)
.HasColumnName("ValueAsString");
modelBuilder.Entity<FooInt>().Property(entity => entity.Value)
.HasColumnName("ValueAsInt");
}
This code will generate a table Foos
with columns Id
, Statement
, Discriminator
, ValueAsString
and ValueAsInt
.此代码将生成一个表Foos
其中包含Id
、 Statement
、 Discriminator
、 ValueAsString
和ValueAsInt
。 More info on the Discrimiator
column can be found here可以在此处找到有关Discrimiator
列的更多信息
You still need to create a class for each Type/column you want to use for T
, I don't think you can get around that.您仍然需要为要用于T
每个类型/列创建一个类,我认为您无法解决这个问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.