【问题标题】:How to abstract Entity Framework model properties如何抽象实体框架模型属性
【发布时间】:2017-10-05 12:44:05
【问题描述】:

我有一个看起来像这样的模型:

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。 这意味着Document 属性必须是具体类型。我想让这段代码易于测试,所以我想将该属性作为ITask 接口所需的接口。解决这个问题的一般方法是什么?

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

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

【问题讨论】:

  • 一个想法可以实现Document : IDocument,定义ITaskITask { IDocument getDocumnet(); },最后提供一个实现:public class Task : ITask { public virtual Document Document { get; set; } public IDocument getDocumnet(){ return this.Document; } }。但未经测试。

标签: c# entity-framework


【解决方案1】:

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

public interface ITask {
    Document Document { get; set; }
}

但是您还说您希望 Document 属性作为接口,这变得很棘手,因为您需要 Task 类中的具体类型。通用接口在这里会有所帮助。

// 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;
    }
}

记住,使用 DBContext 中的具体类型。

关于接口应该放在哪里,相同的程序集还是它们自己的,有很多观点。就个人而言,我将它们放在远离实现类的自己的程序集中。这个问题值得一读: Should I have a separate assembly for interfaces?

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

【讨论】:

  • 从长远来看,我总觉得我最终会将接口移出项目并实现,所以我终于开始从一开始就将它们放入自己的程序集中。
【解决方案2】:

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

业务层模型也可以是不可变的,这可能具有优势。您也可以要求所有属性为例如not-null 在你的构造函数中,然后你可以在整个业务层中依赖它。

当然,您可以争辩说要编写的代码几乎是其两倍。没错,但 IMO 会产生更简洁的代码,因此这是我的首选方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    相关资源
    最近更新 更多