转换器在绑定到 EF 模型时显示 System.Data.Entity.DynamicProxies [英] Converter shows System.Data.Entity.DynamicProxies when bind to EF Model

查看:13
本文介绍了转换器在绑定到 EF 模型时显示 System.Data.Entity.DynamicProxies的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个 WPF MVVM 应用程序.我正在尝试使用转换器在组合框中显示联系人姓名.我认为我不能使用 DisplayMemberPath,因为全名"列不存在.

I am writing a WPF MVVM Application. I am trying to use a converter to display a contact name in the combobox. I do not think I can use the DisplayMemberPath since a "fullname" column does not exist.

ComboBox 正在使用实体框架绑定到类中的类.鉴于以下情况:

The ComboBox is being bound to a class within a class using Entity Framework. Given the following:

.cs 文件

public class Car
{
    public int CarId { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
    public string Year { get; set; }
    public Contact Owner { get; set; }
}

public class Contact 
{
    public int ContactID { get; set; }
    public string Salutation { get; set; }
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }
    public string Suffix { get; set; }
}

public class MultiBindingConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        string name = "";
        if (!(values[0] is Contact Contact))
            return name;

        switch ((string)parameter)
        {
            case "LastNameFirst":
            name += (!string.IsNullOrEmpty(Contact.LastName)) ? Contact.LastName : "";
            name += (!string.IsNullOrEmpty(Contact.Suffix)) ? " " + Contact.Suffix : "";
            name += (!string.IsNullOrEmpty(Contact.FirstName)) ? ", " + Contact.FirstName : "";
            name += (!string.IsNullOrEmpty(Contact.MiddleName)) ? " " + Contact.MiddleName : "";
            name += (!string.IsNullOrEmpty(Contact.Salutation)) ? ", " + Contact.Salutation : "";

            break;
        case "FormatNormal":
        default:
            name += (!string.IsNullOrEmpty(Contact.Salutation)) ? Contact.Salutation : "";
            name += (!string.IsNullOrEmpty(Contact.FirstName)) ? " " + Contact.FirstName : "";
            name += (!string.IsNullOrEmpty(Contact.MiddleName)) ? " " + Contact.MiddleName : "";
            name += (!string.IsNullOrEmpty(Contact.LastName)) ? " " + Contact.LastName : "";
            name += (!string.IsNullOrEmpty(Contact.Suffix)) ? " " + Contact.Suffix : "";
            break;
    }

    return name;
}

public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
    throw new NotImplementedException();
}
}

.XAML 文件

<UserControl.Resources>
    <local:MultiBindingConverter x:Key="MBC" />
</UserControl.Resources>

<ComboBox ItemsSource="{Binding Contacts, Mode=OneTime}" // Contacts is a full list of the Contact Class (so its every Owner)
          SelectedValuePath="ContactId"
          SelectedValue="{Binding Car.Owner.ContactId, Mode=TwoWay}"
          >
<ComboBox.ItemTemplate>
    <DataTemplate>
         <TextBlock>
             <TextBlock.Text>
                  <MultiBinding Converter="{StaticResource MBC}" ConverterParameter="LastNameFirst" >
                      <Binding Path="Contacts"/>
                  </MultiBinding>
             </TextBlock.Text>
         </TextBlock>
    </DataTemplate>
 </ComboBox.ItemTemplate>
 </ComboBox>

问题是组合框中显示的最终结果是:

The issue is that the end result that is displayed in the ComboBox is:

System.Data.Entity.DynamicProxies.Contact_......

System.Data.Entity.DynamicProxies.Contact_.......

它没有以正确的格式显示所有者名称.我怎样才能以这种方式绑定到 ComboBox 以获得我想要的输出(即 Doe Sr., John Michael, Mr.)

It is not showing the Owner name in the correct format. How can I do a binding to the ComboBox in this manner to get the output I desire (ie. Doe Sr., John Michael, Mr.)

编辑我也试过这种方式

EDIT I have also tried it this way

.cs IValueConverter

.cs IValueConverter

public class ContactNameConverter : BaseValueConverter<ContactNameConverter>
{
    public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {

        string name = "";
        if (!(value is Contact Contact))
            return name;

        switch ((string)parameter)
        {
            case "LastNameFirst":
                name += (!string.IsNullOrEmpty(Contact.LastName)) ? Contact.LastName : "";
                name += (!string.IsNullOrEmpty(Contact.Suffix)) ? " " + Contact.Suffix : "";
                name += (!string.IsNullOrEmpty(Contact.FirstName)) ? ", " + Contact.FirstName : "";
                name += (!string.IsNullOrEmpty(Contact.MiddleName)) ? " " + Contact.MiddleName : "";
                name += (!string.IsNullOrEmpty(Contact.Salutation)) ? ", " + Contact.Salutation : "";

                break;
            case "FormatNormal":
            default:
                name += (!string.IsNullOrEmpty(Contact.Salutation)) ? Contact.Salutation : "";
                name += (!string.IsNullOrEmpty(Contact.FirstName)) ? " " + Contact.FirstName : "";
                name += (!string.IsNullOrEmpty(Contact.MiddleName)) ? " " + Contact.MiddleName : "";
                name += (!string.IsNullOrEmpty(Contact.LastName)) ? " " + Contact.LastName : "";
                name += (!string.IsNullOrEmpty(Contact.Suffix)) ? " " + Contact.Suffix : "";
                break;
        }

        return name;

    }

    public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }

}

.XAML

<ComboBox ItemsSource="{Binding Contacts, Mode=OneTime}"
      SelectedValuePath="ContactId"
      SelectedValue="{Binding Car.Owner.ContactId, Mode=TwoWay}"
      >
      <ComboBox.ItemTemplate>
          <DataTemplate>
               <TextBlock Text="{Binding Path=., Converter={local:ContactNameConverter}}"/>
          </DataTemplate>
      </ComboBox.ItemTemplate>
 </ComboBox>

推荐答案

类型 System.Data.Entity.DynamicProxies 被 EF 用作启用延迟加载的代理.您可以通过将 ObjectContext.ContextOptions.ProxyCreationEnabled 设置为 false 来禁用代理创建.链接

The type System.Data.Entity.DynamicProxies is used by EF as a proxy to enable lazy loading. You can disable proxy creation by setting ObjectContext.ContextOptions.ProxyCreationEnabled to false. link

但是,建议使用 ViewModels 而不是 EF Models 作为绑定源.

However, it is recommended to use ViewModels as the source of the binding instead of EF Models.

您还可以将新属性添加到 EF 模型(或最好添加到 VM)作为每个项目的绑定源:

You can also add a new property to an EF Model (or preferably to a VM) as the source of the bindings of each item:

 [NotMapped]
 public string FirstLastName { get { return FirstName + ", " + LastName; } } 

链接

您应该记住,ItemTemplateDataContext 指的是集合的每个元素.所以 Contact 类型的对象的路径是 . 而不是 Contacts.

You should keep in mind that DataContext of ItemTemplate refers to each element of a collection. So the path of an object of type Contact is . not Contacts.

<ComboBox.ItemTemplate>
    <DataTemplate>
         <TextBlock>
             <TextBlock.Text>
                  <MultiBinding Converter="{StaticResource MBC}" ConverterParameter="LastNameFirst" >
                      <Binding Path="."/>
                  </MultiBinding>
             </TextBlock.Text>
         </TextBlock>
    </DataTemplate>
 </ComboBox.ItemTemplate>

我还注意到您使用了具有一个值的多值转换器.你可以这样做:

I also noticed that you used a multi value converter with one value. You could do it like the following:

<ComboBox.ItemTemplate>
    <DataTemplate>
         <TextBlock>
             <TextBlock.Text>
                  <MultiBinding Converter="{StaticResource MBC}" ConverterParameter="LastNameFirst" >
                      <Binding Path="FirstName"/>
                      <Binding Path="LastName"/>
                  </MultiBinding>
             </TextBlock.Text>
         </TextBlock>
    </DataTemplate>
 </ComboBox.ItemTemplate>

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
     if(parameter == "LastNameFirst")
        return string.Format("{0}, {1}", values[0], values[1]);
     else
        return string.Format("{0}, {1}", values[1], values[0]);
}

这篇关于转换器在绑定到 EF 模型时显示 System.Data.Entity.DynamicProxies的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆