작업 단위 및 저장소 패턴에 대한 복수 자습서를 수행했습니다. MVC와 Ef4 구현에 함께 두 가지를 넣으려고합니다. 이 자습서에는 작은 EF 모델이 있으며 두 개의 엔티티 만 있습니다. 따라서 2 개의 엔티티와 일치하는 객체는 네비게이션 속성 등의 ICollection으로 정의되었습니다. 처음에는 코드에서와 같지만 객체와 엔티티 프레임 워크 사이에는 아무런 연관이 없었습니다. 이들은 작업 단위 (UOW)에서 저장소로 집계 된 오브젝트입니다. 그러나 이것이 내가 다음 질문을하기 시작하는 곳입니다.저장소 패턴 + 작업 단위 패턴 + MVC3 + EF4 - 모든 것과 함께 작동하는 모델 데이터 정의 문제
- 엔티티 프레임 워크에서 개체를 사용할 수있을 때 엔티티 프레임 워크에 이미있는 개체의 기본적으로 중복 개체를 만드는 이유는 무엇입니까? 안 그래?
- 이러한 개체를 만드는 경우 전체 ef 모델을 매핑해야합니까? 탐색 속성에 대한 ICollections가 있으면 개체가 정확히 일치하지 않고 기본적으로 대부분의 모델에서 연속적으로 오류가 발생합니다. 이 모델은 12 개가 넘는 엔티티가 포함 된 상당히 크기 때문에 저장소에서 사용되지 않는 엔티티를 생성하지 않아도됩니다.
- 이러한 클래스가 뷰에 보내는 클래스 인 경우 실제 모델 클래스의 버전을 제거해야하는 뷰 모델 클래스가 아닌가요? 이는 내 컨트롤러에서 작업 단위 및 저장소 클래스를 사용하여 데이터를 검색 한 다음 해당 데이터를 제거하고 특정 데이터 조각 만 뷰 모델에 전달한다는 것을 의미합니다. 이제는 작업 단위와 저장소 패턴을 사용하여 방금 얻은 모든 청결 상태가 다시 사라지기 시작한다는 것을 의미합니다.
나는 ...
namespace Data
{
public interface IRepository<T>
where T : class//, IEntity
{
IQueryable<T> FindAll();
IQueryable<T> Find(Expression<Func<T, bool>> predicate);
//T FindById(int id);
void Add(T newEntity);
void Remove(T entity);
}
public class SqlRepository<T> : IRepository<T>
where T : class//, IEntity
{
public SqlRepository(ObjectContext context)
{
_objectSet = context.CreateObjectSet<T>();
}
public IQueryable<T> Find(Expression<Func<T, bool>> predicate)
{
return _objectSet.Where(predicate);
}
public void Add(T newEntity)
{
_objectSet.AddObject(newEntity);
}
public void Remove(T entity)
{
_objectSet.DeleteObject(entity);
}
public IQueryable<T> FindAll()
{
return _objectSet;
}
protected ObjectSet<T> _objectSet;
}
}
public class SqlUnitOfWork : IUnitOfWork
{
public SqlUnitOfWork()
{
var connectionString =
ConfigurationManager
.ConnectionStrings[ConnectionStringName]
.ConnectionString;
_context = new ObjectContext(connectionString);
_context.ContextOptions.LazyLoadingEnabled = true;
}
public IRepository<Domain.Project> Projects
{
get
{
if (_projects == null)
{
_projects = new SqlRepository<Domain.Project>(_context);
}
return _projects;
}
}
public void Commit()
{
_context.SaveChanges();
}
SqlRepository<Domain.Project> _projects = null;
//SqlRepository<TimeCard> _timeCards = null;
readonly ObjectContext _context;
const string ConnectionStringName = "Entities";
}
}
namespace Domain
{
public interface IRepository<T>
where T : class//, IEntity
{
IQueryable<T> FindAll();
IQueryable<T> Find(Expression<Func<T, bool>> predicate);
//T FindById(int id);
void Add(T newEntity);
void Remove(T entity);
}
public interface IUnitOfWork
{
IRepository<Project> Projects { get; }
//IRepository<TimeCard> TimeCards { get; }
void Commit();
}
}
를 다음 코드가 다음 나는 또한 도메인 네임 스페이스에 ... 다음과 같은 방식으로 내 도메인 클래스를 선언했습니다.
public class Project //: IEntity
{
public virtual int ProjectId { get; set; }
public virtual int UserId { get; set; }
public virtual int CategoryId { get; set; }
public virtual string Name { get; set; }
public virtual string Description { get; set; }
// nav prop - do I have to have these?
public virtual ICollection<Image> Images { get; set; }
public virtual ICollection<WatchedProject> WatchedProjects { get; set; }
public virtual ICollection<RequestForProposal> RequestForProposals { get; set; }
public virtual ICollection<Message> Messages { get; set; }
public virtual Category Category { get; set; }
}
는 지금은 그냥이 테스트 그리고 난 다음 콘솔 응용 프로그램 코드가 ...
static void Main(string[] args)
{
IUnitOfWork _unitOfWork = new SqlUnitOfWork();
IRepository<Domain.Project> _repository = _unitOfWork.Projects;
var prjs = _unitOfWork.Projects.FindAll();
foreach (Domain.Project prj in prjs)
{
Console.WriteLine(prj.Description);
}
Console.Read();
}
을하지만이 줄을 실행하면
IRepository<Domain.Project> _repository = _unitOfWork.Projects;
의에 ..
_objectSet = context.CreateObjectSet<T>();
그리고 나는 ... 예외 때문에
System.Data.MetadataException was unhandled
Message=Schema specified is not valid. Errors:
The relationship 'Model.fk_projects_catetegoryid_categories' was not loaded because the type 'Model.Category' is not available.
The following information may be useful in resolving the previous error:
The required property 'ServiceProviderCategories' does not exist on the type 'Domain.Category'.
The relationship 'Model.FK_Messages_Projects_ProjectId' was not loaded because the type 'Model.Message' is not available.
The following information may be useful in resolving the previous error:
The required property 'MessageId' does not exist on the type 'Domain.Message'.
The relationship 'Model.fk_requestforproposals_projectid_projects' was not loaded because the type 'Model.RequestForProposal' is not available.
The following information may be useful in resolving the previous error:
The required property 'Project' does not exist on the type 'Domain.RequestForProposal'.
The relationship 'Model.FK_WatchedProject_ProjectId_Projects' was not loaded because the type 'Model.WatchedProject' is not available.
The following information may be useful in resolving the previous error:
The required property 'WatchedProjectId' does not exist on the type 'Domain.WatchedProject'.
The relationship 'Model.ProjectImage' was not loaded because the type 'Model.Image' is not available.
The following information may be useful in resolving the previous error:
The required property 'ImageId' does not exist on the type 'Domain.Image'.
Source=System.Data.Entity
StackTrace:
at System.Data.Metadata.Edm.ObjectItemCollection.LoadAssemblyFromCache(ObjectItemCollection objectItemCollection, Assembly assembly, Boolean loadReferencedAssemblies, EdmItemCollection edmItemCollection, Action`1 logLoadMessage)
at System.Data.Metadata.Edm.ObjectItemCollection.ImplicitLoadAssemblyForType(Type type, EdmItemCollection edmItemCollection)
at System.Data.Metadata.Edm.MetadataWorkspace.ImplicitLoadAssemblyForType(Type type, Assembly callingAssembly)
at System.Data.Objects.ObjectContext.GetTypeUsage(Type entityCLRType)
at System.Data.Objects.ObjectContext.GetEntitySetFromContainer(EntityContainer container, Type entityCLRType, String exceptionParameterName)
at System.Data.Objects.ObjectContext.GetEntitySetForType(Type entityCLRType, String exceptionParameterName)
at System.Data.Objects.ObjectContext.CreateObjectSet[TEntity]()
at Data.SqlRepository`1..ctor(ObjectContext context) in C:\Projects\TestProjectClasses\Data\SqlRepository.cs:line 18
at Data.SqlUnitOfWork.get_Projects() in C:\Projects\TestProjectClasses\Data\SqlUnitOfWork.cs:line 31
at TestProjectClasses.Program.Main(String[] args) in C:\Projects\TestProjectClasses\TestProjectClasses\Program.cs:line 26
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
해당 개체가 내 도메인 네임 스페이스에 생성되지 않았기 때문에 나는이 예외가 ...하지만 모든 객체의 복사본을 만들 싶지 않아
. 나는 약간의 연구를했지만 모든 연구를했다. 그러나 나는이 객체들을 어떤 시점에서 변환해야 할 필요가 있다고 생각합니다 ... 컨트롤러 코드에 많은 변환 논리를 넣는 것보다 더 나은 방법이 있습니까? EF에 정의
리포지토리와 작업 단위 패턴으로 이동하기 전에 EF에 대한 이해를 해시 할 수 있습니다. 간단한 모델, 아마도 두 개의 관련 엔티티 만 사용하고 EF가 작동하는 방식과 진행 상황에 대한 느낌을 얻으십시오. 데이터 어노테이션 및 EF 모델 생성을 도와주는 방법에 대해 읽어보십시오. 또한 데이터 컨텍스트가있는 모든 클래스가 IDisposable을 구현해야하는 이유를 조사하십시오. 그런 다음 뷰 모델에 대한 많은 질문을 살펴볼 수 있습니다. 이러한 몇 가지 문제의 세부 사항을 살펴 보는 대신 더 많은 연구를해야한다는 전반적인 필요성을 강조하십시오. –
저는이 기술에 대한 전문가가 아니지만 조금만 노력해 봤습니다. pluralsight 자습서는 이러한 모든 동일한 기술로 만들어졌습니다. 이 튜토리얼은 엔티티 프레임 워크에 묶이지 않은 엔티티의 사본을 만들기에 충분한 시간을 보냈습니다. 그들은 데이터베이스에서 모델을 생성하고 코드를 먼저 사용하지 않았습니다. poco 클래스는 단순히 ... poco 클래스였습니다 ... EF가 사용할 모든 것을 함께 묶을 DBContext는 없었습니다. 그들은 시각적 모델과 디자이너를 사용했습니다. 그래서 저는 왜 그 길이로 가서 복사본을 만들고 그 같은 방법으로 ef 등을 모방하려고합니다. –
@TravisJ UnitOfWork가 엔티티 자체를 직접 사용할 수있게 만들었 기 때문에 필연적이지는 않습니다. 그러나 전체 모델의 복사 클래스를 만드는 데 어떤 이유가 있었는지 알고 싶습니다. –