Рассматривали ли вы создание документов сущность аннотация ?
Со стороны БД у вас будет таблица Documents , содержащая только поля, общие для всех счетов / предложений / и т. Д. Это поле будет иметь идентификатор ID PK - например, DocId.
В других таблицах могут храниться дополнительные метаданные, специфичные для этого документа, и PK представляет собой поле (не-IDENTITY) DocId, которое также является FK для таблицы Documents .
На стороне EF Документы становится абстрактной сущностью, а другие сущности наследуются от этой сущности. Это позволяет существовать хорошей парадигме OO и делает ваш код более надежным.
В настоящее время мы используем эту схему (EF4 / SQL Server).
Ваш сценарий звучит очень похоже на наш - рассмотрите возможность использования абстрактных классов.
EDIT
Думаю, я бы добавил немного больше информации о том, как я на самом деле реализовал этот сценарий, чтобы поставить вас на правильный путь.
Что касается комментариев к вашему состоянию Q, у нас мало знаний о вашем домене, поэтому сложно составить обоснованное мнение. Лично я решил сделать свою сущность абстрактной , потому что определенные функции требовали, чтобы «смешанная сумка» предметов была возвращена за один удар. Конечно, есть и другие способы сделать это (например, хранимая процедура), но это обеспечивает хороший свободный интерфейс между моим пользовательским интерфейсом (кстати, MVC) и моим сервисным уровнем.
Работает так - вот как я получаю сингл Пост:
// var is strongly-typed to a "Post"
var somePost = repository.FindSingle(10);
Вот как я получаю смешанную сумку сообщений:
// var is strongly-typed to a "ICollection<Post>".
// "Title" is a property on my "Post" abstract POCO
var mixedBagOfPosts = repository.FindAll<Post>(p => p.Title = "Some Title");
Вот как я могу получить коллекцию "Отзывы" (потомок Почты):
// var is strongly-typed to a "ICollection<Review>"
// "Rating" is a property on my "Review" POCO (derived from Post)
var reviews = repository.FindAll<Review>(r => r.Rating == 5.00);
Кикер в моем репозитории реализован с помощью дженериков, а параметр type обеспечивает безопасность типов:
ICollection<T> FindAll<T>(Expression<Func<T,bool>> predicate) where T : Post
И это реализовано так:
return myContext.Posts.OfType<T>.Where(predicate).ToList();
OfType вызывает внутреннее соединение с T (которая является дочерней таблицей), поэтому возвращаются только эти записи.
Конечно, у меня также есть сервисный уровень , являющийся посредником между моим пользовательским интерфейсом и хранилищем, но это должно привести вас на правильный путь.
Кроме того, вам не нужно разбираться со всей предикатом Expression, мне это нравится, потому что он минимизирует количество методов в моем интерфейсе и дает полную мощность запросов моим контроллерам, обеспечивая при этом запросы отложено до уровня сервисного уровня, но не дальше.
Если вам это не нравится, у вас могут быть обычные параметры (заголовок строки и т. Д.).
Как я уже сказал, эта архитектура соответствует моим требованиям к домену, поэтому она не обязательно может соответствовать вашим, но, надеюсь, даст вам некоторое представление.