ValueIjector (NuGet의 최신 버전)를 사용하여 내 뷰 모델에 EntityFramework Code First 개체의 데이터를 주입하려고합니다. 나는 이것의 반대도하고 싶을 것이다. 그러나 이것은 내가 시작하고있는 시도이다.엔티티를 뷰 모델에 매핑하기 위해 사용자 정의 값 삽입을 어떻게 만듭니 까? 시도 포함
나는 다양한 매핑을 연구했으며 그 중 많은 시도를 해왔다. 나는 내가 필요한 것을하는 사람을 찾지 못했고, 나의 필요는 오히려 기본적인 것이라고 생각합니다. (그래서이 질문들 중 몇 가지는 각각 다른 대답을 얻습니다.).
나는 이것에 관해 나의 실사를 정말로 시도했다. 내가 봤 거든 및 CodePlex trolled ProDinner 응용 프로그램을 다운로드 한 (그것을 실행하고 디버그에서 코드를 단계별로).
저는 injecton을 처리 할 자체 ValueInjection 클래스가있는 지점에 있습니다. 나는 코드와 객체를 꽤 친숙한 방식으로 붙이기 때문에 코드와 객체를 잡아서 실행할 수 있습니다. 기본 LoopValueInjection을 사용하는 솔루션이 있지만 기본 엔티티에서 매핑으로 이동 한 다음 엔티티에 매핑하는 수동 배관이 필요하기 때문에 마음에 들지 않습니다. ProDinner 예제는 필자가 선호하는 템플릿 방식이 더 많았지 만 필자의 요구에 맞출 수 없었습니다.
내 코드가 논리적으로 엉망이라고 생각하는 이유는 소스 속성 유형이 단순한 개체가 아니라면 재귀 적 주입을 강제로 수행하는 방법을 이해할 수 없다는 것입니다. 이 예제에서 Person.Address. * 속성은 이름으로 일치하고 PersonViewModel 클래스의 속성을 입력합니다. 그러나 인젝션은 Person의 속성을 반복하고 Person.Address 속성의 이름과 유형을 일치 시키려고합니다.
내가이 재귀를 수행 할 것인가 라인 Object result = Activator.CreateInstance(c.SourceProp.Type)
.InjectFrom<CloneInjection>(c.SourceProp.Value);
생각,하지만 난 그것을하지 생각하지 않습니다.
그럼 ... 아무에게도이 문제를 해결할 수있는 방법을 알려 줄 수 있습니까?
////// ENTITY MODELS
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual Address Address { get; set; }
}
public class Address
{
public int Id { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
}
////// VIEW MODEL
public class PersonViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int PersonId { get; set; }
public int AddressId { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
}
////// CUSTOM INJECTOR
public class EntityToViewModel : ConventionInjection
{
protected override bool Match(ConventionInfo c)
{
//ignore int = 0 and DateTime = to 1/01/0001
if (c.SourceProp.Type == typeof(DateTime) && (DateTime)c.SourceProp.Value == default(DateTime) ||
(c.SourceProp.Type == typeof(int) && (int)c.SourceProp.Value == default(int)))
return false;
if (c.SourceProp.Name == c.TargetProp.Name && c.SourceProp.Value != null)
return true;
if (c.SourceProp.Type == typeof(int) &&
c.TargetProp.Type == typeof(int))
{
if("id".Equals(c.SourceProp.Name.ToLower()) &&
c.TargetProp.Name.ToLower().EndsWith("id") &&
c.TargetProp.Name.StartsWith(c.Source.Type.Name))
return true;
}
//Transition logic to SetValue for value types. This should
//allow Address values on Person to be set.
if (!c.SourceProp.Type.IsPrimitive || c.SourceProp.Type.Equals(typeof(string)))
return true;
return false;
//put id logic matching here
//return c.SourceProp.Name == c.TargetProp.Name && c.SourceProp.Value != null;
}
protected override object SetValue(ConventionInfo c)
{
//If type is primative or string return the value as is
if (c.SourceProp.Type.IsPrimitive || c.SourceProp.Type.Equals(typeof(string)))
return c.SourceProp.Value;
Object result = Activator.CreateInstance(c.SourceProp.Type)
.InjectFrom<CloneInjection>(c.SourceProp.Value);
//for simple object types create a new instace and apply the clone injection on it
return result;
}
}
////// Program.cs
public class Program
{
public static void Main(string[] args)
{
Person defaultPerson = getDefaultPerson();
//Throws an error. I'm not sure where in the pipeline this occurs, but
//it seems to happen somewhere other than the Match & SetValue method of
//my EntityToViewModel injection
PersonViewModel pvm = CreateFromEntity(defaultPerson);
//Works, but want it more generic & without having to
//include hardcoded prefix for every non-simple object on my EF Model
pvm = CreateFromEntityWorking(defaultPerson);
Console.ReadLine();
}
private static PersonViewModel CreateFromEntity(Person person)
{
PersonViewModel pvm = new PersonViewModel();
pvm.InjectFrom<EntityToViewModel>(person);
return pvm;
}
///WORKING MAPPING BUT SEEMS TOO HARDCODED
private static PersonViewModel CreateFromEntityWorking(Person person)
{
PersonViewModel personvm = new PersonViewModel();
//Fill out view model properties with the same name as those on Person
personvm.InjectFrom(new LoopValueInjection().TargetPrefix("Person"), person);
if (person != null && person.Address != null)
{
//Fill out view model properties for the Address
personvm.InjectFrom(new LoopValueInjection().TargetPrefix("Address"), person.Address);
}
return personvm;
}
public static Person getDefaultPerson()
{
Person p = new Person();
Address a = new Address();
p.Id = 1;
p.FirstName = "John";
p.LastName = "McClain";
a.City = "New York";
a.State = "New York";
a.Zip = "55555";
a.Id = 2;
p.Address = a;
return p;
}
}