Xamarin Forms 和 EntityFramework Attributes 兼容性



我有一个使用C#WPFASP.NET WebAPIEntity Framework客户端/服务器解决方案。客户端和服务器分支在他的项目之间共享模型。现在我正在尝试创建一个新客户端,使用 Xamarin 窗体并将模型共享到,但实体框架属性(MaxLengthIndexNotMapped等)在 PCL 中不兼容。所以这是我尝试过的事情:

将Microsoft.EntityFrameworkCore 导入 PCL 模型

如此处所述,您应该能够将实体框架与 Xamarin 表单一起使用,因此我将 PCL 转换为 NetStandard 1.3,它可以工作,允许每个 EntityFramework 属性。但是现在服务器项目与该标准不兼容,我无法在模型项目中添加prism和Newtonsoft.Json等包。

使用诱饵和切换技巧模拟 Xamarin 表单的属性

我尝试了此处描述的方法,该方法基于在模型 PCL 中创建自定义属性,并在类库中重新定义它们。MyClient.Droid 和 MyClient.UWP 重新定义属性,将其留空,MyServer 将使用实体框架功能重新定义它们。

自定义索引属性 - 模型 PCL:

namespace Model.Compatibility
{
public class IndexAttribute : Attribute
{
public IndexAttribute()
{
}
}
}

自定义索引属性 - 服务器端:

[assembly: TypeForwardedToAttribute(typeof(Model.Compatibility.IndexAttribute))]
namespace Model.Compatibility
{
public class MockedIndexAttribute : System.ComponentModel.DataAnnotations.Schema.IndexAttribute
{
public MockedIndexAttribute()
{
}
}
}

我测试了这个叫var attribute = new Model.Compatibility.IndexAttribute();的 aproach.从不调用 MockedIndexAttribute 构造函数。

创建共享项目而不是 PCL

这种方式有点混乱,但看起来有效。只需为模型创建一个新的共享项目,并使用如下条件标志:

#if !__MOBILE__
[NotMapped, Index]
#endif
public Guid Id { get; set; }

我目前还没有完全部署这种方法,但是如果我不能使前两种方法都不起作用,我将采用这种方法。

编辑 - 尝试使"诱饵和切换属性"方法起作用

正如@AdamPedley和这个线程所到的那样,我在一个新的PCL(Xamarin.Compatibility )中重新定义了IndexAttribute,使用与原始命名空间相同的命名空间:

namespace System.ComponentModel.DataAnnotations.Schema
{
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class IndexAttribute : Attribute
{
public IndexAttribute() { }
}
}

现在,我的 PCL 模型包含对 Xamarin.Compatibility 的引用,因此我可以在模型属性中使用 Index 属性:

[Index]
public Guid Id { get; set; }

然后,从我的服务器项目中,我调用下一行代码来检查调用的构造函数、自定义属性或 EntityFramework 定义的构造函数:

PropertyInfo prop = typeof(MyClass).GetProperty("Id");
object[] attributes = prop.GetCustomAttributes(true);

调用的构造函数是自定义构造函数,因此它不起作用,因为它必须调用 EntityFramework 定义的属性。这是我不知道的事情,使我的模型的 PCL 根据调用程序集选择自定义属性或 EF 属性的机制是什么。

我还在我的服务器项目中添加了一个名为TypeForwarding.Net.cs(如此处所示)的文件,其中包含:

[assembly: TypeForwardedTo(typeof(IndexAttribute))]

但仍然不起作用。

我相信EF fluent API是PCL和NetStandard友好的。因此,您可以创建 POCO 对象,并让流畅的 api 执行跨平台映射,而不是使用属性。msdn.microsoft.com/en-us/library/jj591617(v=vs.113).aspx

注意:我使用EF6和PCL项目在MVC/WPF/移动设备之间共享的项目做到了这一点

最新更新