[英]Trying to create a data pipeline with Rx .Net
我一直在尝试使用Rx .Net对某些数据进行管道传输,但是我真的很努力。
我有一系列未保存的Foos,其中包含一些数据。 团队创建了酒吧的集合。 保存条之后,如果条具有BarId,则使用Foo中的数据和Bar中的BarId创建Baz。 一旦创建了Foo的所有Bar和Baz,便清除了Foo的数据并保存了Foo。 这些是类:
public class Base
{
public Guid Id { get; set; } = Guid.Empty;
public override string ToString()
{
return $"{GetType().Name}::Id:{Id}";
}
public Task<Unit> Save()
{
Id = Guid.NewGuid();
Console.WriteLine($"{ToString()} (save)");
return Task.FromResult(Unit.Default);
}
}
public sealed class Foo : Base
{
public long FooId { get; }
public string Data { get; private set; }
public override string ToString()
{
return $"{base.ToString()},FooId:{FooId},Data:{Data ?? "NULL"}";
}
public Task<Unit> ClearData()
{
Data = null;
return Task.FromResult(Unit.Default);
}
public Foo(long index)
{
FooId = index;
Data = $"Foo({index})";
Console.WriteLine($"{ToString()} (ctor)");
}
}
public class Map : Base
{
public int Index { get; }
public string Mapping { get; }
public Guid BarId { get; protected set; } = Guid.Empty;
public sealed override string ToString()
{
return $"{base.ToString()},Index:{Index},BarId:{BarId},Mapping:{Mapping}";
}
protected Map(int index, string data, Func<string, string> mapper)
{
Mapping = mapper(data);
Index = index;
}
}
public sealed class Bar : Map
{
public Bar(int index, string data, Func<string, string> mapper) : base(index, data, mapper)
{
if (new Random().Next(3) > 0)
{
BarId = Guid.NewGuid();
Console.WriteLine($"{ToString()} (ctor)");
}
}
}
public sealed class Baz : Map
{
public Baz(int index, Guid barId, string data, Func<string, string> mapper) : base(index, data, mapper)
{
BarId = barId;
Console.WriteLine($"{ToString()} (ctor)");
}
}
我尝试了很多事情,但这是我最想要的东西:
var foos = Observable.Interval(TimeSpan.FromSeconds(1)).Take(2).Select(i => new Foo(i));
var units = from foo in foos
let idxs = Observable.Range(1, 3)
from idx in idxs
let bar = new Bar(idx, foo.Data, s => $"{s}Bar")
from barSaved in bar.Save()
where bar.BarId != Guid.Empty
let baz = new Baz(idx, bar.BarId, foo.Data, s => $"{s}Baz")
from bazSaved in baz.Save()
from fooChanged in foo.ClearData()
from fooSaved in foo.Save()
select Unit.Default;
units.Subscribe();
它会创建适当数量的Bar和Baz,但每次创建保存的Baz时都会保存Foo,否则就不会保存Foo。
我希望有人可以帮助我,也许我还将学到有关反应式编程的新知识,这将有助于我更好地理解该范例。
编辑:
我尝试将随机数提供程序移动到静态实例,但是没有用。 这是显示发生了什么的一些输出:
Foo::Id:00000000-0000-0000-0000-000000000000,FooId:0,Data:Foo(0) (ctor)
Bar::Id:00000000-0000-0000-0000-000000000000,Index:1,BarId:00000000-0000-0000-0000-000000000000,Mapping:Foo(0)Bar (ctor)
Bar::Id:28789b8b-03d4-4160-97f2-b2cbafd80c73,Index:1,BarId:00000000-0000-0000-0000-000000000000,Mapping:Foo(0)Bar (save)
Bar::Id:00000000-0000-0000-0000-000000000000,Index:2,BarId:81e79b81-6692-406f-a025-448cd203cb73,Mapping:Foo(0)Bar (ctor)
Bar::Id:d43d2e43-b812-4657-9e4f-a5b875a595fb,Index:2,BarId:81e79b81-6692-406f-a025-448cd203cb73,Mapping:Foo(0)Bar (save)
Baz::Id:00000000-0000-0000-0000-000000000000,Index:2,BarId:81e79b81-6692-406f-a025-448cd203cb73,Mapping:Foo(0)Baz (ctor)
Baz::Id:fdf464d1-9240-49e4-89cd-dbab758159fc,Index:2,BarId:81e79b81-6692-406f-a025-448cd203cb73,Mapping:Foo(0)Baz (save)
Foo::Id:04d9d819-26bc-41dc-8f1b-a0e509acd2e5,FooId:0,Data:NULL (save)
Bar::Id:00000000-0000-0000-0000-000000000000,Index:3,BarId:6894c1f0-d776-496f-9da4-4f272a338f90,Mapping:Bar (ctor)
Bar::Id:6b82fc20-80ff-41bd-848d-a115f58392c4,Index:3,BarId:6894c1f0-d776-496f-9da4-4f272a338f90,Mapping:Bar (save)
Baz::Id:00000000-0000-0000-0000-000000000000,Index:3,BarId:6894c1f0-d776-496f-9da4-4f272a338f90,Mapping:Baz (ctor)
Baz::Id:fa361c43-ee07-44cc-8628-4835fce6da9d,Index:3,BarId:6894c1f0-d776-496f-9da4-4f272a338f90,Mapping:Baz (save)
Foo::Id:6f423cf5-8260-4d98-a0bc-4762893b5fe4,FooId:0,Data:NULL (save)
Foo::Id:00000000-0000-0000-0000-000000000000,FooId:1,Data:Foo(1) (ctor)
Bar::Id:00000000-0000-0000-0000-000000000000,Index:1,BarId:5a79b126-27d8-43a1-9bb6-4d28394d5710,Mapping:Foo(1)Bar (ctor)
Bar::Id:94f5842f-eb1c-4248-a70a-dac5eb843cc1,Index:1,BarId:5a79b126-27d8-43a1-9bb6-4d28394d5710,Mapping:Foo(1)Bar (save)
Baz::Id:00000000-0000-0000-0000-000000000000,Index:1,BarId:5a79b126-27d8-43a1-9bb6-4d28394d5710,Mapping:Foo(1)Baz (ctor)
Baz::Id:d46b1d7e-eda2-4c63-8810-830e3416e975,Index:1,BarId:5a79b126-27d8-43a1-9bb6-4d28394d5710,Mapping:Foo(1)Baz (save)
Foo::Id:e198e636-bfd7-49c5-a260-346524ec4019,FooId:1,Data:NULL (save)
Bar::Id:00000000-0000-0000-0000-000000000000,Index:2,BarId:00000000-0000-0000-0000-000000000000,Mapping:Bar (ctor)
Bar::Id:206a8796-32da-493f-9582-7c551781e2d5,Index:2,BarId:00000000-0000-0000-0000-000000000000,Mapping:Bar (save)
Bar::Id:00000000-0000-0000-0000-000000000000,Index:3,BarId:154481ad-33c3-49d7-af2b-3f7738f1f692,Mapping:Bar (ctor)
Bar::Id:ffda6907-93b0-411f-aa40-3fee790b52cb,Index:3,BarId:154481ad-33c3-49d7-af2b-3f7738f1f692,Mapping:Bar (save)
Baz::Id:00000000-0000-0000-0000-000000000000,Index:3,BarId:154481ad-33c3-49d7-af2b-3f7738f1f692,Mapping:Baz (ctor)
Baz::Id:2071927f-27d6-4df6-a74f-1c0bdfbba8d5,Index:3,BarId:154481ad-33c3-49d7-af2b-3f7738f1f692,Mapping:Baz (save)
Foo::Id:07460e6e-d3db-4ed8-a441-e16f06cd908a,FooId:1,Data:NULL (save)
如您所见,保存Baz时,Foo将清除其数据并保存,从而使所有后续的Bar和Baz丢失其数据-看到其Mapping没有Foo(index)。
编辑:
我要实现的目标是,一旦创建并保存了Foo的所有 Bars和Bazs,则只有Foo的数据被清除并完成保存。
编辑源代码以包括跟踪。
我认为您的问题是if (new Random().Next(3) > 0)
。 Random
对象从系统时钟开始播种,因此,如果快速连续调用此代码,您将获得相同的值。 尝试这种方式:
public sealed class Bar : Map
{
public static Random _rand = new Random();
public Bar(int index, string data, Func<string, string> mapper) : base(index, data, mapper)
{
if (_rand.Next(3) > 0)
{
BarId = Guid.NewGuid();
}
}
}
看来可以给出正确的结果。
我将Random
实例保留在方法之外,然后尝试以下方法:
var units =
from foo in foos
from inner in
(
from idx in Observable.Range(1, 3)
let bar = new Bar(idx, foo.Data, s => $"{s}Bar")
from barSaved in bar.Save()
where bar.BarId != Guid.Empty
let baz = new Baz(idx, bar.BarId, foo.Data, s => $"{s}Baz")
from bazSaved in baz.Save()
select Unit.Default
).ToArray()
from fooChanged in foo.ClearData()
from fooSaved in foo.Save()
select Unit.Default;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.