2

먼저 코드를 사용하여 List 속성에 간단한 쿼리를 수행하여 필터링 목록에 문자열이 포함되어 있는지 확인하려고합니다. 그러나 나는 문제가있다. 간단히하기 위해 다음을 가정하십시오.EF 4 : 비 스칼라 변수 참조가 지원되지 않음

public class Person 
{ 
    public List<string> FavoriteColors { get; set; } 
} 

//Now some code. Create and add to DbContext 
var person = new Person{ FavoriteColors = new List<string>{ "Green", "Blue"} }; 
dbContext.Persons.Add(person); 
myDataBaseContext.SaveChanges(); 

//Build 
var filterBy = new List<string>{ "Purple", "Green" }; 
var matches = dbContext.Persons.AsQueryable(); 
matches = from p in matches 
      from color in p.FavoriteColors 
      where filterBy.Contains(color) 
      select p; 

내가 FavoriteColors이 문자열 인 경우 통화를 포함 수행 할 수 있기 때문에 JSON 직렬화 된 문자열이 변환되어 고려하고 옵션. 또는, 나는 배 밖으로 갈 수 있고 "색상"엔티티를 만들 수 있지만 상당히 무거운 무게입니다. 불행히도 열거 형은 지원되지 않습니다.

답변

1

나는 문제가 컬렉션이 아니라 matches에 대한 참조라고 생각한다. 당신이 Known Issues and Considerations for EF4을 선택하면

var matches = dbContext.Persons.AsQueryable(); 
matches = from p in matches 
      from color in p.FavoriteColors 
      where filterBy.Contains(color) 
      select p; 

이 더 많거나 적게 정확히 언급 한 경우입니다. 이러한 엔티티로

비 스칼라 변수를 참조하는 은 질의에서 지원되지 된다. 이러한 쿼리를 실행하면 NotSupportedException이 예외 형 EntityType 상수 값을 생성 "없음 알리는 메시지를 발생 이다.

또한 구체적 스칼라 변수들의 집합을 참조 있다고 유의 . 지원 (즉 EF 4 IMO의 새로운 기능)

는 다음과 같은 일을해야했다 가졌 (지금 그것을 밖으로 시도 할 수 없음) :

matches = from p in dbContext.Persons 
      from color in p.FavoriteColors 
      where filterBy.Contains(color) 
      select p; 
+0

예제가 작동하지 않습니다. LOCAL 스칼라 변수의 집합을 참조 할 수 있지만 특정 엔터티의 경우 비 엔터티의 컬렉션 속성을 참조 할 수 없습니다. 예를 들어, p.FavorieColor (string)가있는 경우 "filterBy.Contains (p.FavoriteColor)"를 사용할 수 있지만 collection 속성을 통해 반복 할 수는 없습니다. –

0

이 제한을 극복하기 위해 "StringEntity"클래스를 작성하여 실험하기로 결정했으며 암시 적 연산자를 사용하여 문자열을 쉽게 변환 할 수있었습니다. 이 (무거운이기는하지만) 몇 가지 테스트를 완벽하게 작동 것처럼

public class MyClass 
{ 
    [Key, DatabaseGenerated(DatabaseGenerationOption.Identity)] 
    public Guid Id { get; set; } 
    public List<StringEntity> Animals { get; set; } 
    public MyClass() 
    { 
     List<StringEntity> Animals = List<StringEntity>(); 
    } 
} 
public class StringEntity 
{ 
    [Key, DatabaseGenerated(DatabaseGenerationOption.Identity)] 
    public Guid Id { get; set; } 
    public string Value { get; set; } 

    public StringEntity(string value) { Value = value; } 
    public static implicit operator string(StringEntity se) { return se.Value; } 
    public static implicit operator StringEntity(string value) { return new StringEntity(value); } 
} 
public class MyDbContext : DbContext 
{   
    public DbSet<MyClass> MyClasses { get; set; }  

    protected override void OnModelCreating(ModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<MyClass>() 
      .HasMany(x => x.Animals) 
      .WithMany() 
      .Map(x => 
      { 
       x.MapLeftKey(l => l.Id, "MyClassId"); 
       x.MapRightKey(r => r.Id, "StringEntityId"); 
      }); 
    } 
} 

이 ... 모든 모습, 그리고 나는 MVC3보기에, 원래의 목적을 위해 다중 선택 목록 상자를 구현 : 솔루션은 아래를 참조하십시오. ListBox에 동일한 NAME이 Entity Collection Property로 할당 된 경우 알 수없는 이유 때문에 선택한 항목이로드되지 않습니다.

작동하지 않았다 다음을 설명하기 위해 :

//#1 Unpluralize the ListBox name so that is doesn't match the name Model.Animals 
var animalOptions = new string[] {"Dog", "Cat", "Goat"}; 
@Html.ListBox("Animal", new MultiSelectList(animalOptions, Model.Animals.Select(x => x.Value))) 

//#2 Use JQuery to replace the id and name attribute, so that binding can occur on the form post 
<script type="text/javascript"> 
    jQuery(function ($) { 
    $("select#Animal").attr("name", "Animals").attr("id", "Animals"); 
    }); 
</script> 

//#3 Create a model binder class to handle List<StringEntity> objects 
public class StringEntityListBinder : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
    var stringArray = controllerContext.HttpContext.Request.Params.GetValues(bindingContext.ModelName); 
    return stringArray.Select(x => new StringEntity(x)).ToList(); 
    } 
} 

//#4 Initialize the binder in your Global.asax setup. 
ModelBinders.Binders.Add(typeof(List<StringEntity>), new StringEntityListBinder()); 

참고 목록 상자가 : // 면도기 코드보기

string[] animalOptions = new string[] {"Dog", "Cat", "Goat"}; 
string[] animalSelections = new string[] {"Dog", "Cat"}; 
Html.ListBox("Animals", Multiselect(animalOptions, animalSelections)); 

를이 제한을 해결하기 위해, 나는 네 가지를 할 필요가 속성이 문자열 목록 일 때 버그가 발생하지 않았으며 항목 목록 일 때 버그가 발생했습니다.

관련 문제