Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何抽象实体框架模型属性_C#_Entity Framework - Fatal编程技术网

C# 如何抽象实体框架模型属性

C# 如何抽象实体框架模型属性,c#,entity-framework,C#,Entity Framework,我有一个这样的模型: public class Task : ITask { public int DocumentId { get; set; } public virtual Document Document { get; set; } public TaskType TaskType { get; } public string Value { get; } } 现在,这个类直接注册为DbContext中的DbSet。 这意味着文档属性必须是具体类型。我

我有一个这样的模型:

public class Task : ITask
{
    public int DocumentId { get; set; }
    public virtual Document Document { get; set; }
    public TaskType TaskType { get; }
    public string Value { get; }
}
现在,这个类直接注册为
DbContext
中的
DbSet
。 这意味着
文档
属性必须是具体类型。我希望使此代码易于测试,因此我希望将属性作为
ITask
接口所需的接口。处理这个问题的一般方法是什么

我想到的一种方法是将所有此类类放在一个单独的程序集中,但这似乎有点不合适


编辑:
ITask
接口是在不同的程序集中定义的,因此它不应该知道
文档的类型。

接口中可以定义属性,因此您的ITask可以指定文档,如下所示:

public interface ITask {
    Document Document { get; set; }
}
但是您还说您希望Document属性作为接口,这变得很棘手,因为您需要任务类中的具体类型。通用接口在这里会有所帮助

// The interfaces
public interface ITask<TDocument> where TDocument : IDocument, new() {
     TDocument Document { get; set; }
}

public interface IDocument {
    int Number { get; set; } // Example property
}


//The classes
public class Document : IDocument{
    public int Number { get; set; } // Example property
}

public class Task : ITask<Document> {
    public Document Document { get; set; }
}


// See if it works
public class Test {
    private Task myTask = new Task();

    public void TestMethod() {
        myTask.Document.Number = 1;
    }
}
//接口
公共接口ITask,其中t文档:IDocument,new(){
t文档文档{get;set;}
}
公共接口IDocument{
int Number{get;set;}//示例属性
}
//班级
公共类文档:IDocument{
公共整数{get;set;}//示例属性
}
公共类任务:ITask{
公共文档文档{get;set;}
}
//看看它是否有效
公开课考试{
私有任务myTask=新任务();
公共void TestMethod(){
myTask.Document.Number=1;
}
}
记住,在DBContext中使用具体类型

至于接口应该位于何处,相同的程序集还是它们自己的,对此有很多观点。就我个人而言,我把它们放在自己的程序集中,远离实现类。这个问题值得一读:


还有一条注释,类名任务在.Net线程库中使用,因此可能值得考虑更改它以避免潜在的混淆。

接口中可以定义属性,因此您的ITask可以指定文档,如下所示:

public interface ITask {
    Document Document { get; set; }
}
但是您还说您希望Document属性作为接口,这变得很棘手,因为您需要任务类中的具体类型。通用接口在这里会有所帮助

// The interfaces
public interface ITask<TDocument> where TDocument : IDocument, new() {
     TDocument Document { get; set; }
}

public interface IDocument {
    int Number { get; set; } // Example property
}


//The classes
public class Document : IDocument{
    public int Number { get; set; } // Example property
}

public class Task : ITask<Document> {
    public Document Document { get; set; }
}


// See if it works
public class Test {
    private Task myTask = new Task();

    public void TestMethod() {
        myTask.Document.Number = 1;
    }
}
//接口
公共接口ITask,其中t文档:IDocument,new(){
t文档文档{get;set;}
}
公共接口IDocument{
int Number{get;set;}//示例属性
}
//班级
公共类文档:IDocument{
公共整数{get;set;}//示例属性
}
公共类任务:ITask{
公共文档文档{get;set;}
}
//看看它是否有效
公开课考试{
私有任务myTask=新任务();
公共void TestMethod(){
myTask.Document.Number=1;
}
}
记住,在DBContext中使用具体类型

至于接口应该位于何处,相同的程序集还是它们自己的,对此有很多观点。就我个人而言,我把它们放在自己的程序集中,远离实现类。这个问题值得一读:


还有一条评论,类名任务是在.Net线程库中使用的,因此可能值得考虑更改它以避免潜在的混淆。

我将仅对数据访问层使用EF模型,并为业务层创建单独的模型。数据访问层将负责将EF模型映射到业务层模型,并将其交给业务层

然后,业务层模型也可以是不可变的,这可能具有优势。此外,您还可以要求构造函数中的所有属性都不为null,然后您可以在整个业务层中依赖这些属性


当然,您可能会争辩说,要编写的代码几乎是原来的两倍。的确如此,但在我看来,it会带来更干净的代码,因此这是我的首选方法。

我只会对数据访问层使用EF模型,并为业务层创建一个单独的模型。数据访问层将负责将EF模型映射到业务层模型,并将其交给业务层

然后,业务层模型也可以是不可变的,这可能具有优势。此外,您还可以要求构造函数中的所有属性都不为null,然后您可以在整个业务层中依赖这些属性


当然,您可能会争辩说,要编写的代码几乎是原来的两倍。这是真的,但在我看来,它会产生更干净的代码,因此这是我首选的方法。

一个想法可以是实现
文档:IDocument
,将
ITask
定义为
ITask{IDocument getDocumnet();}
,最后提供一个实现:
公共类任务:ITask{public virtual Document Document{get;set;}public IDocument getDocumnet(){return this.Document;}}
.Untested。一个想法可以实现
Document:IDocument
,将
ITask
定义为
ITask{IDocument getDocumnet();}
,最后提供一个实现:
公共类任务:ITask{public virtual Document Document{get;set;}public IDocument getDocumnet(){return this.Document;}
。但未经测试。从长远来看,我总觉得我最终会随着实现将接口移出项目,所以我最终开始从现在开始将它们放入自己的程序集中。从长远来看,我总觉得我会随着实现将接口移出项目,所以我最终开始了j我们必须从现在开始把它们放在自己的组件中。