gpt4 book ai didi

c# - 使用linq和automapper在dto中将属性序列化为复杂类型

转载 作者:太空宇宙 更新时间:2023-11-03 15:25:15 25 4
gpt4 key购买 nike

我很难找出看似“简单”的问题。我正在使用 Microsoft Azure 移动应用程序 .Net 后端、MSSQL 数据库、 Entity Framework 代码优先和 AutoMapper。所以我有以下对象:

public class Route
{
public string Id { get; set; }
[...] //some other properties
public string SerializedGoogleRoute { get; set; }
}

public class DtoRoute
{
public string Id { get; set; }
[...]
public DtoGoogleRoute GoogleRoute { get; set; }
}

public class DtoGoogleRoute
{
[...] //only strings, ints,...
}

所以我想做的是:在数据库中将 GoogleRoute 保存为序列化字符串,因为它由许多属性组成,我不需要将它们放在不同的列中 - 我只希望它作为一个列中的序列化字符串路由实体。当 Route 对象投影到 DtoRoute 对象时,我希望 GoogleRoute 被序列化,反之亦然。

因为我使用的是 LINQ/queryables,所以我只能使用几个 AutoMapper 映射选项(参见 AutoMapper wiki )。没有这些,我无法让它工作。

我面临的问题/我尝试过的:我无法在映射时将字符串序列化/反序列化为 DtoGoogleRoute(使用 MapFrom 或 ConstructProjectionUsing),因为 LINQ 显然无法将 JsonConvert.Serialize/Deserialize 方法转换为 SQL 语句。

我尝试在 Route 对象中使用 DtoGoogleRoute 属性,在 DtoRoute 对象中使用字符串属性,并使用 getter/setter 执行(反)序列化。这在自定义 API Controller 中几乎完美地工作,但是由于 OData 查询过滤器,Azure 移动应用程序 .Net 后端再次在表 Controller 中使用,只有序列化的字符串属性返回给客户端(因为 OData/LINQ 不知道其他属性).

另一个选择是使用 Entity Framework 从 DtoGoogleRoute 中创建复杂类型 - 这工作正常但不适用于 AutoMapper,因为 AutoMapper 无法处理复杂类型。

目前,我正在使用自定义 API Controller ,这很有效。但是最好使用tablecontroller,因为它们支持离线同步。

我无法想象这么简单的事情(至少我认为这是一件简单的事情)做不到或者很难做。但也许问题在于涉及的所有组件(表 Controller 、OData、LINQ、EF、AutoMapper)。

如果有人能提供帮助,我将不胜感激。

[编辑]:我认为它与普通 api Controller 一起工作而不与 tablecontroller 一起工作这一事实与 OData 有关。我尝试将相同的代码放入 tablecontroller 方法和 API Controller 方法中。当调用 API Controller 方法时,我可以在服务器上看到它只是调用此函数并将所有正确的属性返回给客户端(使用 fiddler 检查)。但是当调用 tablecontroller 方法时,tablecontroller 方法将 URL“重写”为 OData URL --> 我认为这是因为某些 EnableQuery 或其他 OData 属性。因为here (虽然不是 AutoMapper,但它似乎是 Microsoft 的一个类似项目)它说 EnableQuery 属性被调用了两次——也是在请求离开服务器时。我认为它削减了 GoogleRoute 属性,因为它不知道 OData 元数据或类似内容中的此属性。

最佳答案

你可以这样实现——

internal class RouteToDtoConverter : TypeConverter<Route, DtoRoute>
{
protected override DtoRoute ConvertCore(Route source)
{
return new DtoRoute
{
Id = source.Id,
GoogleRoute = JsonConvert.DeserializeObject<DtoGoogleRoute>(source.SerializedGoogleRoute)
};
}
}

internal class DtoToRouteConverter : TypeConverter<DtoRoute, Route>
{
protected override Route ConvertCore(DtoRoute source)
{
return new Route
{
Id = source.Id,
SerializedGoogleRoute = JsonConvert.SerializeObject(source.GoogleRoute)
};
}
}

public class Route
{
public string Id { get; set; }

public string SerializedGoogleRoute { get; set; }
}

public class DtoRoute
{
public string Id { get; set; }

public DtoGoogleRoute GoogleRoute { get; set; }
}

public class DtoGoogleRoute
{
public int MyProperty { get; set; }
public int MyProperty2 { get; set; }
}


AutoMapper.Mapper.CreateMap<Route, DtoRoute>()
.ConvertUsing(new RouteToDtoConverter());

AutoMapper.Mapper.CreateMap<DtoRoute, Route>()
.ConvertUsing(new DtoToRouteConverter());

var res = Mapper.Map<DtoRoute>(new Route
{
Id = "101",
SerializedGoogleRoute = "{'MyProperty':'90','MyProperty2':'09'}"
});

var org = Mapper.Map<Route>(res); //pass

关于c# - 使用linq和automapper在dto中将属性序列化为复杂类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35602996/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com